This commit is contained in:
Jeonghyeon Ha 2025-08-12 14:13:56 +09:00
commit 0ecab97059
2 changed files with 109 additions and 67 deletions

View File

@ -1,44 +1,56 @@
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using Unity.VisualScripting;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine;
using Object = UnityEngine.Object;
namespace DDD
{
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 Prop = "Prop_";
private const string BaseUpper = "_BASE";
private const string NormalUpper = "_NORMAL";
public enum EnvPrefabType
private const string BaseMapPropertyName = "_BaseMap";
private const string NormalMapPropertyName = "_NormalMap";
private static readonly Dictionary<EnvPrefabType, HashSet<string>> PrefabTargetPaths = new()
{
{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,
Food,
Geometry
Item,
Geometry,
Ground,
}
public static void OnPreprocessTexture(TextureImporter importer)
{
var path = importer.assetPath;
string fileNameUpper = Utils.FileName(path).ToUpper();
if (fileNameUpper.Contains(NormalUpper))
if (IsTextureMatchingPropertyBySuffix(fileNameUpper, NormalMapPropertyName))
{
importer.textureType = TextureImporterType.NormalMap;
}
else if (fileNameUpper.Contains(BaseUpper))
else if (IsTextureMatchingPropertyBySuffix(fileNameUpper, BaseMapPropertyName))
{
importer.textureType = TextureImporterType.Sprite;
importer.spriteImportMode = SpriteImportMode.Single;
@ -62,32 +74,43 @@ public static void OnRemove(string path, string movePath = "")
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)
{
string upperPath = path.ToUpper();
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
if (upperPath.Contains(ExtenstionConstants.PngExtensionUpper) == false)
{
// Not a texture.
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)
{
var di = new DirectoryInfo(path);
@ -98,13 +121,13 @@ public static void BuildMaterialAndPrefab(string path, EnvPrefabType prefabType)
string addrRoot = PathConstants.AddressablesFolderPath; // "/_Addressables"
string destDir = path.Replace(rawRoot, addrRoot);
string materialPath = $"{destDir}/{folderName}{ExtenstionConstants.MaterialExtenstionLower}";
string prefabPath = $"{destDir}/{prefabType.ToString()}{folderName}{ExtenstionConstants.PrefabExtenstionLower}";
string materialPath = $"{destDir}/{GetMaterialPrefix()}{folderName}{ExtenstionConstants.MaterialExtenstionLower}";
string prefabPath = $"{destDir}/{GetPrefabPrefix(prefabType)}{folderName}{ExtenstionConstants.PrefabExtenstionLower}";
Utils.MakeFolderFromFilePath(materialPath);
bool bShouldCreateMaterial = false;
bShouldCreateMaterial = prefabType != EnvPrefabType.Food; // Add conditions if needed.
bShouldCreateMaterial = prefabType != EnvPrefabType.Item; // Add conditions if needed.
if (bShouldCreateMaterial)
{
// 머티리얼 생성 또는 로드
@ -124,8 +147,10 @@ public static void BuildMaterialAndPrefab(string path, EnvPrefabType prefabType)
Sprite tex = AssetDatabase.LoadAssetAtPath<Sprite>(file);
if (tex == null) continue;
// 셰이더 프로퍼티명과 텍스처 파일명의 접미사 매칭
if (IsTextureMatchingPropertyBySuffix(texName, BaseUpper))
if (IsTextureMatchingPropertyBySuffix(texName, BaseMapPropertyName))
{
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)
{
string[] aliases = GetPropertyAliases(propertyName);
foreach (var alias in aliases)
{
if (textureName.ToUpper().EndsWith(alias.ToUpper()))
{
return true;
}
}
// 셰이더 프로퍼티명에서 접미사 추출 (예: _BaseMap -> BASEMAP)
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)
@ -235,11 +288,12 @@ private static bool InstantiatePrefabByType(string folderName, string prefabPath
return true;
}
string prefix = prefabType.ToString() + "_";
instancePrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (instancePrefab == null)
{
instancePrefab = (GameObject)PrefabUtility.InstantiatePrefab(basePrefab);
instancePrefab.name = $"{Prop}{folderName}";
instancePrefab.name = $"{prefix}{folderName}";
}
return false;
@ -247,34 +301,26 @@ private static bool InstantiatePrefabByType(string folderName, string prefabPath
private static string GetBasePrefabPath(EnvPrefabType prefabType)
{
return prefabType switch
if (BasePrefabPaths.TryGetValue(prefabType, out var path))
{
EnvPrefabType.Prop => BasePrefabPath_Prop,
EnvPrefabType.Food => BasePrefabPath_Food,
EnvPrefabType.Geometry => BasePrefabPath_Geometry,
_ => BasePrefabPath_Prop
};
return path;
}
Debug.LogError($"Base prefab path not found: {prefabType}");
return "";
}
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 AddressablesFolderPath = "/_Addressables";
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