Merge pull request '환경 프랍 자동화 변경' (#20) from feature/env_auto_create into develop
Reviewed-on: #20
This commit is contained in:
commit
f2b898d71d
@ -1,44 +1,56 @@
|
|||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Unity.VisualScripting;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.AddressableAssets;
|
using UnityEditor.AddressableAssets;
|
||||||
using UnityEditor.AddressableAssets.Settings;
|
using UnityEditor.AddressableAssets.Settings;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public static class AssetPostprocessorEnvironment
|
public static class AssetPostprocessorEnvironment
|
||||||
{
|
{
|
||||||
private static readonly HashSet<string> PropTargetPaths = new();
|
|
||||||
private static readonly HashSet<string> FoodTargetPaths = new();
|
|
||||||
private static readonly HashSet<string> GeometryTargetPaths = new();
|
|
||||||
|
|
||||||
private const string BasePrefabPath_Prop = "Assets/_DDD/_Raw/Environments/Env_Mesh_Prop.prefab";
|
|
||||||
private const string BasePrefabPath_Geometry = "Assets/_DDD/_Raw/Environments/Env_Mesh_Geometry.prefab";
|
|
||||||
private const string BasePrefabPath_Food = "Assets/_DDD/_Raw/Environments/Env_Unlit_Food.prefab";
|
|
||||||
private const string ShaderName = "Universal Render Pipeline/LitEnvironment";
|
private const string ShaderName = "Universal Render Pipeline/LitEnvironment";
|
||||||
private const string Prop = "Prop_";
|
private const string BaseMapPropertyName = "_BaseMap";
|
||||||
private const string BaseUpper = "_BASE";
|
private const string NormalMapPropertyName = "_NormalMap";
|
||||||
private const string NormalUpper = "_NORMAL";
|
|
||||||
|
private static readonly Dictionary<EnvPrefabType, HashSet<string>> PrefabTargetPaths = new()
|
||||||
public enum EnvPrefabType
|
{
|
||||||
|
{EnvPrefabType.Prop, new HashSet<string>()},
|
||||||
|
{EnvPrefabType.Item, new HashSet<string>() },
|
||||||
|
{EnvPrefabType.Geometry, new HashSet<string>() },
|
||||||
|
{EnvPrefabType.Ground, new HashSet<string>() },
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Dictionary<EnvPrefabType, string> BasePrefabPaths = new()
|
||||||
|
{
|
||||||
|
{ EnvPrefabType.Prop, "Assets/_DDD/_Raw/Environments/Env_Mesh_Prop.prefab" },
|
||||||
|
{ EnvPrefabType.Item, "Assets/_DDD/_Raw/Environments/Env_Unlit_Item.prefab" },
|
||||||
|
{ EnvPrefabType.Geometry, "Assets/_DDD/_Raw/Environments/Env_Mesh_Geometry.prefab" },
|
||||||
|
{ EnvPrefabType.Ground, "Assets/_DDD/_Raw/Environments/Env_Mesh_Ground.prefab" },
|
||||||
|
};
|
||||||
|
|
||||||
|
public enum EnvPrefabType : uint
|
||||||
{
|
{
|
||||||
Prop,
|
Prop,
|
||||||
Food,
|
Item,
|
||||||
Geometry
|
Geometry,
|
||||||
|
Ground,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnPreprocessTexture(TextureImporter importer)
|
public static void OnPreprocessTexture(TextureImporter importer)
|
||||||
{
|
{
|
||||||
var path = importer.assetPath;
|
var path = importer.assetPath;
|
||||||
string fileNameUpper = Utils.FileName(path).ToUpper();
|
string fileNameUpper = Utils.FileName(path).ToUpper();
|
||||||
|
|
||||||
if (fileNameUpper.Contains(NormalUpper))
|
if (IsTextureMatchingPropertyBySuffix(fileNameUpper, NormalMapPropertyName))
|
||||||
{
|
{
|
||||||
importer.textureType = TextureImporterType.NormalMap;
|
importer.textureType = TextureImporterType.NormalMap;
|
||||||
}
|
}
|
||||||
else if (fileNameUpper.Contains(BaseUpper))
|
else if (IsTextureMatchingPropertyBySuffix(fileNameUpper, BaseMapPropertyName))
|
||||||
{
|
{
|
||||||
importer.textureType = TextureImporterType.Sprite;
|
importer.textureType = TextureImporterType.Sprite;
|
||||||
importer.spriteImportMode = SpriteImportMode.Single;
|
importer.spriteImportMode = SpriteImportMode.Single;
|
||||||
@ -62,32 +74,43 @@ public static void OnRemove(string path, string movePath = "")
|
|||||||
AddTargetPath(path);
|
AddTargetPath(path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetEnvironmentPath(EnvPrefabType prefabType)
|
||||||
|
{
|
||||||
|
string prefabPath = PathConstants.RawEnvironmentsPathUpper + prefabType.ToString();
|
||||||
|
prefabPath = prefabPath.ToUpper();
|
||||||
|
return prefabPath;
|
||||||
|
}
|
||||||
|
|
||||||
private static void AddTargetPath(string path)
|
private static void AddTargetPath(string path)
|
||||||
{
|
{
|
||||||
string upperPath = path.ToUpper();
|
string upperPath = path.ToUpper();
|
||||||
|
if (upperPath.Contains(ExtenstionConstants.PngExtensionUpper) == false)
|
||||||
if (upperPath.Contains(PathConstants.RawEnvPathUpper_Prop) &&
|
|
||||||
upperPath.Contains(ExtenstionConstants.PngExtensionUpper))
|
|
||||||
{
|
|
||||||
PropTargetPaths.Add(path);
|
|
||||||
}
|
|
||||||
else if (upperPath.Contains(PathConstants.RawEnvPathUpper_Food) &&
|
|
||||||
upperPath.Contains(ExtenstionConstants.PngExtensionUpper))
|
|
||||||
{
|
|
||||||
FoodTargetPaths.Add(path);
|
|
||||||
}
|
|
||||||
else if(upperPath.Contains(PathConstants.RawEnvPathUpper_Geometry) &&
|
|
||||||
upperPath.Contains(ExtenstionConstants.PngExtensionUpper))
|
|
||||||
{
|
|
||||||
GeometryTargetPaths.Add(path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// Not a texture.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (uint i = 0; i < PrefabTargetPaths.Count; i++)
|
||||||
|
{
|
||||||
|
var prefabType = (EnvPrefabType)i;
|
||||||
|
var targetPaths = PrefabTargetPaths[prefabType];
|
||||||
|
if (upperPath.Contains(GetEnvironmentPath(prefabType)))
|
||||||
|
{
|
||||||
|
targetPaths.Add(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetPrefabPrefix(EnvPrefabType prefabType)
|
||||||
|
{
|
||||||
|
return prefabType.ToString() + "_";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetMaterialPrefix()
|
||||||
|
{
|
||||||
|
return "Mat_";
|
||||||
|
}
|
||||||
|
|
||||||
public static void BuildMaterialAndPrefab(string path, EnvPrefabType prefabType)
|
public static void BuildMaterialAndPrefab(string path, EnvPrefabType prefabType)
|
||||||
{
|
{
|
||||||
var di = new DirectoryInfo(path);
|
var di = new DirectoryInfo(path);
|
||||||
@ -98,13 +121,13 @@ public static void BuildMaterialAndPrefab(string path, EnvPrefabType prefabType)
|
|||||||
string addrRoot = PathConstants.AddressablesFolderPath; // "/_Addressables"
|
string addrRoot = PathConstants.AddressablesFolderPath; // "/_Addressables"
|
||||||
|
|
||||||
string destDir = path.Replace(rawRoot, addrRoot);
|
string destDir = path.Replace(rawRoot, addrRoot);
|
||||||
string materialPath = $"{destDir}/{folderName}{ExtenstionConstants.MaterialExtenstionLower}";
|
string materialPath = $"{destDir}/{GetMaterialPrefix()}{folderName}{ExtenstionConstants.MaterialExtenstionLower}";
|
||||||
string prefabPath = $"{destDir}/{prefabType.ToString()}{folderName}{ExtenstionConstants.PrefabExtenstionLower}";
|
string prefabPath = $"{destDir}/{GetPrefabPrefix(prefabType)}{folderName}{ExtenstionConstants.PrefabExtenstionLower}";
|
||||||
|
|
||||||
Utils.MakeFolderFromFilePath(materialPath);
|
Utils.MakeFolderFromFilePath(materialPath);
|
||||||
|
|
||||||
bool bShouldCreateMaterial = false;
|
bool bShouldCreateMaterial = false;
|
||||||
bShouldCreateMaterial = prefabType != EnvPrefabType.Food; // Add conditions if needed.
|
bShouldCreateMaterial = prefabType != EnvPrefabType.Item; // Add conditions if needed.
|
||||||
if (bShouldCreateMaterial)
|
if (bShouldCreateMaterial)
|
||||||
{
|
{
|
||||||
// 머티리얼 생성 또는 로드
|
// 머티리얼 생성 또는 로드
|
||||||
@ -124,8 +147,10 @@ public static void BuildMaterialAndPrefab(string path, EnvPrefabType prefabType)
|
|||||||
Sprite tex = AssetDatabase.LoadAssetAtPath<Sprite>(file);
|
Sprite tex = AssetDatabase.LoadAssetAtPath<Sprite>(file);
|
||||||
if (tex == null) continue;
|
if (tex == null) continue;
|
||||||
// 셰이더 프로퍼티명과 텍스처 파일명의 접미사 매칭
|
// 셰이더 프로퍼티명과 텍스처 파일명의 접미사 매칭
|
||||||
if (IsTextureMatchingPropertyBySuffix(texName, BaseUpper))
|
if (IsTextureMatchingPropertyBySuffix(texName, BaseMapPropertyName))
|
||||||
|
{
|
||||||
CreateSpritePrefabVariantIfNotExist(folderName, tex, prefabPath, prefabType);
|
CreateSpritePrefabVariantIfNotExist(folderName, tex, prefabPath, prefabType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,13 +195,41 @@ private static void MatchTexturesToShaderProperties(Shader shader, string[] file
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string[] GetPropertyAliases(string propertyName)
|
||||||
|
{
|
||||||
|
if (propertyName == "_BaseMap")
|
||||||
|
{
|
||||||
|
return new[] {"_Base", "_BC", "BaseColor"};
|
||||||
|
}
|
||||||
|
if (propertyName == "_NormalMap")
|
||||||
|
{
|
||||||
|
return new[] {"_Normal", "_Bump", "_BumpMap", "_N"};
|
||||||
|
}
|
||||||
|
if (propertyName == "_MOHS")
|
||||||
|
{
|
||||||
|
return new[] {"_Mask"};
|
||||||
|
}
|
||||||
|
if (propertyName == "_Emiss")
|
||||||
|
{
|
||||||
|
return new[] {"_Emissive", "_Emission", "_E"};
|
||||||
|
}
|
||||||
|
return Array.Empty<string>();
|
||||||
|
}
|
||||||
private static bool IsTextureMatchingPropertyBySuffix(string textureName, string propertyName)
|
private static bool IsTextureMatchingPropertyBySuffix(string textureName, string propertyName)
|
||||||
{
|
{
|
||||||
|
string[] aliases = GetPropertyAliases(propertyName);
|
||||||
|
foreach (var alias in aliases)
|
||||||
|
{
|
||||||
|
if (textureName.ToUpper().EndsWith(alias.ToUpper()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 셰이더 프로퍼티명에서 접미사 추출 (예: _BaseMap -> BASEMAP)
|
// 셰이더 프로퍼티명에서 접미사 추출 (예: _BaseMap -> BASEMAP)
|
||||||
string propertySuffix = propertyName.TrimStart('_').ToUpper();
|
string propertySuffix = propertyName.TrimStart('_').ToUpper();
|
||||||
|
|
||||||
// 텍스처 파일명이 해당 접미사로 끝나는지 확인
|
// 텍스처 파일명이 해당 접미사로 끝나는지 확인
|
||||||
return textureName.Contains($"_{propertySuffix}");
|
return textureName.EndsWith($"_{propertySuffix}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateMaterialPrefabVariantIfNotExist(string folderName, Material mat, string prefabPath, EnvPrefabType prefabType)
|
private static void CreateMaterialPrefabVariantIfNotExist(string folderName, Material mat, string prefabPath, EnvPrefabType prefabType)
|
||||||
@ -235,11 +288,12 @@ private static bool InstantiatePrefabByType(string folderName, string prefabPath
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string prefix = prefabType.ToString() + "_";
|
||||||
instancePrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
instancePrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
||||||
if (instancePrefab == null)
|
if (instancePrefab == null)
|
||||||
{
|
{
|
||||||
instancePrefab = (GameObject)PrefabUtility.InstantiatePrefab(basePrefab);
|
instancePrefab = (GameObject)PrefabUtility.InstantiatePrefab(basePrefab);
|
||||||
instancePrefab.name = $"{Prop}{folderName}";
|
instancePrefab.name = $"{prefix}{folderName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -247,34 +301,26 @@ private static bool InstantiatePrefabByType(string folderName, string prefabPath
|
|||||||
|
|
||||||
private static string GetBasePrefabPath(EnvPrefabType prefabType)
|
private static string GetBasePrefabPath(EnvPrefabType prefabType)
|
||||||
{
|
{
|
||||||
return prefabType switch
|
if (BasePrefabPaths.TryGetValue(prefabType, out var path))
|
||||||
{
|
{
|
||||||
EnvPrefabType.Prop => BasePrefabPath_Prop,
|
return path;
|
||||||
EnvPrefabType.Food => BasePrefabPath_Food,
|
}
|
||||||
EnvPrefabType.Geometry => BasePrefabPath_Geometry,
|
Debug.LogError($"Base prefab path not found: {prefabType}");
|
||||||
_ => BasePrefabPath_Prop
|
return "";
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BuildTarget()
|
public static void BuildTarget()
|
||||||
{
|
{
|
||||||
foreach (var path in PropTargetPaths)
|
foreach (var envTargets in PrefabTargetPaths)
|
||||||
{
|
{
|
||||||
BuildMaterialAndPrefab(Utils.FolderPath(path), EnvPrefabType.Prop);
|
var envType = envTargets.Key;
|
||||||
|
var TargetPaths= envTargets.Value;
|
||||||
|
foreach (var path in TargetPaths)
|
||||||
|
{
|
||||||
|
BuildMaterialAndPrefab(Utils.FolderPath(path), envType);
|
||||||
|
}
|
||||||
|
TargetPaths.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var path in FoodTargetPaths)
|
|
||||||
{
|
|
||||||
BuildMaterialAndPrefab(Utils.FolderPath(path), EnvPrefabType.Food);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var path in GeometryTargetPaths)
|
|
||||||
{
|
|
||||||
BuildMaterialAndPrefab(Utils.FolderPath(path), EnvPrefabType.Geometry);
|
|
||||||
}
|
|
||||||
PropTargetPaths.Clear();
|
|
||||||
FoodTargetPaths.Clear();
|
|
||||||
GeometryTargetPaths.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,6 @@ public static class PathConstants
|
|||||||
public const string RawFolderPath = "/_Raw";
|
public const string RawFolderPath = "/_Raw";
|
||||||
public const string AddressablesFolderPath = "/_Addressables";
|
public const string AddressablesFolderPath = "/_Addressables";
|
||||||
public const string RawEnvironmentsPathUpper = "ASSETS/_DDD/_RAW/ENVIRONMENTS/";
|
public const string RawEnvironmentsPathUpper = "ASSETS/_DDD/_RAW/ENVIRONMENTS/";
|
||||||
public const string RawEnvPathUpper_Tile = "ASSETS/_DDD/_RAW/ENVIRONMENTS/TILES/";
|
|
||||||
public const string RawEnvPathUpper_Prop = "ASSETS/_DDD/_RAW/ENVIRONMENTS/PROPS/";
|
|
||||||
public const string RawEnvPathUpper_Food = "ASSETS/_DDD/_RAW/ENVIRONMENTS/FOODS/";
|
|
||||||
public const string RawEnvPathUpper_Geometry = "ASSETS/_DDD/_RAW/ENVIRONMENTS/GEOMETRIES/";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ExtenstionConstants
|
public static class ExtenstionConstants
|
||||||
|
Loading…
Reference in New Issue
Block a user