76 lines
2.6 KiB
C#
76 lines
2.6 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
public class SyncFBXMaterialToPrefab : Editor
|
|
{
|
|
[MenuItem("Assets/材质工具/同步 FBX 材质到对应 Prefab", true)]
|
|
static bool Validate()
|
|
{
|
|
return Selection.assetGUIDs.Any(guid => AssetDatabase.GUIDToAssetPath(guid).EndsWith(".fbx"));
|
|
}
|
|
|
|
[MenuItem("Assets/材质工具/同步 FBX 材质到对应 Prefab")]
|
|
static void SyncMaterialsFromFBX()
|
|
{
|
|
foreach (string guid in Selection.assetGUIDs)
|
|
{
|
|
string fbxPath = AssetDatabase.GUIDToAssetPath(guid);
|
|
if (!fbxPath.EndsWith(".fbx")) continue;
|
|
|
|
GameObject fbxModel = AssetDatabase.LoadAssetAtPath<GameObject>(fbxPath);
|
|
if (fbxModel == null) continue;
|
|
|
|
string prefabPath = Path.ChangeExtension(fbxPath, ".prefab");
|
|
|
|
prefabPath = prefabPath.Replace("Models", "Prefabs");
|
|
|
|
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogWarning($"未找到对应的 prefab: {prefabPath}");
|
|
continue;
|
|
}
|
|
|
|
// 获取 FBX 中当前 remap 的材质信息(用名字匹配 Renderer 路径)
|
|
var fbxRenderers = fbxModel.GetComponentsInChildren<Renderer>(true);
|
|
var fbxMatMap = fbxRenderers.ToDictionary(
|
|
r => GetRelativePath(r.transform, fbxModel.transform),
|
|
r => r.sharedMaterials
|
|
);
|
|
|
|
GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
|
|
bool hasChanged = false;
|
|
|
|
foreach (var renderer in instance.GetComponentsInChildren<Renderer>(true))
|
|
{
|
|
string path = GetRelativePath(renderer.transform, instance.transform);
|
|
if (fbxMatMap.TryGetValue(path, out var remappedMats))
|
|
{
|
|
renderer.sharedMaterials = remappedMats;
|
|
hasChanged = true;
|
|
Debug.Log($"✔ 替换 Renderer 材质: {path}");
|
|
}
|
|
}
|
|
|
|
if (hasChanged)
|
|
{
|
|
PrefabUtility.SaveAsPrefabAsset(instance, prefabPath);
|
|
Debug.Log($"✅ 已同步材质到 Prefab: {prefabPath}");
|
|
}
|
|
|
|
Object.DestroyImmediate(instance);
|
|
}
|
|
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
static string GetRelativePath(Transform current, Transform root)
|
|
{
|
|
if (current == root) return current.name;
|
|
return GetRelativePath(current.parent, root) + "/" + current.name;
|
|
}
|
|
}
|