200 lines
7.3 KiB (Stored with Git LFS)
C#
200 lines
7.3 KiB (Stored with Git LFS)
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Superlazy;
|
|
using UnityEditor;
|
|
using UnityEditor.Animations;
|
|
using UnityEngine;
|
|
|
|
public interface IPostProcessorModel
|
|
{
|
|
void OnCreatePrefab(string path, GameObject model);
|
|
}
|
|
|
|
public static class SLAssetPostprocessorModel
|
|
{
|
|
private static readonly HashSet<string> targetPaths = new HashSet<string>();
|
|
|
|
private static string GetDestPath(string path)
|
|
{
|
|
return SLFileUtility.FolderPath(path).Replace("/Raw/", "/Addressables/") + ".prefab";
|
|
}
|
|
|
|
private static string GetPrefabPath(string path)
|
|
{
|
|
var targetName = SLFileUtility.FolderName(path);
|
|
var targetPath = SLFileUtility.FolderPath(path);
|
|
|
|
if (SLFileUtility.FolderName(path) == "Materials")
|
|
{
|
|
targetName = SLFileUtility.FolderName(targetPath);
|
|
targetPath = SLFileUtility.FolderPath(targetPath);
|
|
}
|
|
|
|
return targetPath + "/" + targetName + ".prefab";
|
|
}
|
|
|
|
private static string GetTargetFBX(string path)
|
|
{
|
|
var targetName = SLFileUtility.FolderName(path);
|
|
var targetPath = SLFileUtility.FolderPath(path);
|
|
|
|
if (SLFileUtility.FolderName(path) == "Materials")
|
|
{
|
|
targetName = SLFileUtility.FolderName(targetPath);
|
|
targetPath = SLFileUtility.FolderPath(targetPath);
|
|
}
|
|
|
|
return targetPath + "/" + targetName + ".FBX";
|
|
}
|
|
|
|
public static void OnPreprocessModel(ModelImporter importer)
|
|
{
|
|
importer.materialImportMode = ModelImporterMaterialImportMode.None;
|
|
importer.generateSecondaryUV = false;
|
|
importer.importAnimation = false;
|
|
importer.animationType = ModelImporterAnimationType.Generic;
|
|
importer.avatarSetup = ModelImporterAvatarSetup.CreateFromThisModel;
|
|
}
|
|
|
|
public static void OnRemove(string path)
|
|
{
|
|
var upperPath = path.ToUpper();
|
|
if (upperPath.IsLeft("ASSETS/RAW/UNITS/") && (upperPath.Contains(".FBX") || upperPath.Contains(".MAT")))
|
|
{
|
|
if (SLFileUtility.FolderName(path) != SLFileUtility.FileName(path)) return;
|
|
var newPath = GetDestPath(path);
|
|
AssetDatabase.DeleteAsset(newPath);
|
|
|
|
var prefabPath = GetPrefabPath(path);
|
|
AssetDatabase.DeleteAsset(prefabPath);
|
|
|
|
targetPaths.Add(GetTargetFBX(path)); // 삭제되어도 리빌드
|
|
}
|
|
}
|
|
|
|
public static void OnAdd(string path)
|
|
{
|
|
var upperPath = path.ToUpper();
|
|
if (upperPath.IsLeft("ASSETS/RAW/UNITS/") && (upperPath.Contains(".FBX") || upperPath.Contains(".MAT")))
|
|
{
|
|
if (SLFileUtility.FolderName(path) != SLFileUtility.FileName(path)) return;
|
|
targetPaths.Add(GetTargetFBX(path));
|
|
}
|
|
else if (upperPath.IsLeft("ASSETS/RAW/UNITS/") && upperPath.Contains("_PREFAB.PREFAB"))
|
|
{
|
|
targetPaths.Add(GetPrefabPath(path).Replace(".prefab", "_Prefab.prefab"));
|
|
}
|
|
}
|
|
|
|
public static void CreatePrefab(string path, string destPath)
|
|
{
|
|
try
|
|
{
|
|
var modelCreateComponents = new List<IPostProcessorModel>();
|
|
modelCreateComponents.CreateInstanceList();
|
|
var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
|
|
|
if (go == null) return;
|
|
|
|
var prefab = new GameObject(go.name);
|
|
var model = Object.Instantiate(go);
|
|
model.name = "Model";
|
|
model.transform.SetParent(prefab.transform);
|
|
model.AddComponent<UnitAnimatorController>();
|
|
|
|
var guids = AssetDatabase.FindAssets("t:Material", new string[] { SLFileUtility.FolderPath(path) });
|
|
var materials = guids.Select(guid => AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(guid))).ToDictionary(m => m.name);
|
|
|
|
foreach (var renderer in model.GetComponentsInChildren<Renderer>())
|
|
{
|
|
var sharedMaterials = new Material[renderer.sharedMaterials.Length]; // Material을 직접 엘리먼트로 대입하면 안되고 배열을 통으로 넣어야함
|
|
for (var i = 0; i < renderer.sharedMaterials.Length; ++i)
|
|
{
|
|
if (materials.TryGetValue($"{renderer.name}_{i + 1}", out var numMat))
|
|
{
|
|
sharedMaterials[i] = numMat;
|
|
}
|
|
else if (materials.TryGetValue(renderer.name, out var mat))
|
|
{
|
|
sharedMaterials[i] = mat;
|
|
}
|
|
else if (materials.TryGetValue(go.name, out var defaultMat))
|
|
{
|
|
sharedMaterials[i] = defaultMat;
|
|
}
|
|
else
|
|
{
|
|
sharedMaterials[i] = renderer.sharedMaterials[i];
|
|
// 에러인가? 잠깐 파일 안갖다놨을뿐인가?
|
|
}
|
|
}
|
|
renderer.sharedMaterials = sharedMaterials;
|
|
}
|
|
|
|
var res = prefab.AddComponent<SLResourceObject>();
|
|
|
|
foreach (var comp in modelCreateComponents)
|
|
{
|
|
comp.OnCreatePrefab(destPath, model);
|
|
}
|
|
|
|
res.Init();
|
|
|
|
SLFileUtility.MakeFolderFromFilePath(destPath);
|
|
|
|
{
|
|
// Make Duumy(for test)
|
|
var dummyObj = Object.Instantiate(model);
|
|
var anim = dummyObj.GetComponentInChildren<Animator>();
|
|
var controller = AnimatorController.CreateAnimatorControllerAtPath(GetPrefabPath(path).Replace(".prefab", ".controller"));
|
|
|
|
anim.runtimeAnimatorController = controller;
|
|
var rootStateMachine = controller.layers[0].stateMachine;
|
|
|
|
var clipids = AssetDatabase.FindAssets("t:AnimationClip", new string[] { SLFileUtility.FolderPath(path) });
|
|
foreach (var guid in clipids)
|
|
{
|
|
var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(AssetDatabase.GUIDToAssetPath(guid));
|
|
if (clip != null)
|
|
{
|
|
var state = rootStateMachine.AddState(clip.name);
|
|
state.motion = clip;
|
|
}
|
|
}
|
|
|
|
var dummy = PrefabUtility.SaveAsPrefabAssetAndConnect(dummyObj, GetPrefabPath(path), InteractionMode.AutomatedAction);
|
|
|
|
Object.DestroyImmediate(dummyObj, false);
|
|
}
|
|
|
|
AssetDatabase.DeleteAsset(destPath);
|
|
var newPreafb = PrefabUtility.SaveAsPrefabAssetAndConnect(prefab, destPath, InteractionMode.AutomatedAction);
|
|
|
|
Object.DestroyImmediate(prefab, false);
|
|
Debug.Log("Build : " + destPath, newPreafb);
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
Debug.LogError("Cant build " + destPath + "\n" + e);
|
|
}
|
|
}
|
|
|
|
public static void BuildTarget()
|
|
{
|
|
foreach (var path in targetPaths)
|
|
{
|
|
CreatePrefab(path, GetDestPath(path));
|
|
}
|
|
|
|
targetPaths.Clear();
|
|
}
|
|
|
|
internal static void OnPreprocessTexture(TextureImporter importer)
|
|
{
|
|
importer.sRGBTexture = true;
|
|
importer.mipmapEnabled = false;
|
|
importer.streamingMipmaps = false;
|
|
importer.wrapMode = TextureWrapMode.Clamp;
|
|
importer.filterMode = FilterMode.Bilinear;
|
|
}
|
|
} |