환경 프랍 자동화 변경

This commit is contained in:
Jeonghyeon Ha 2025-08-12 14:05:18 +09:00
parent a8ee601eb1
commit 87d82126c9
2 changed files with 109 additions and 67 deletions

View File

@ -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();
} }
} }
} }

View File

@ -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