[Unity]自动将断链的Prefab替换为真Prefab
2019/10
23
20:10
环境:Unity2018.4
起因:美术在Runtime环境,拉出的Prefab是实例化之后的(断链了)
现在要将原来的Perfab替换为真的Prefab(看起来是蓝色的)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public static class EditorPrefabToolV2
{
static private readonly string[] CFindPaths = new string[]
{
"Assets/Arts/",
};
private static bool InFindPath(string assetPath)
{
foreach(var cfp in CFindPaths)
{
if (assetPath.StartsWith(cfp))
{
return true;
}
}
return false;
}
private static string FindAsset(string assetName)
{
var allAssetPaths = AssetDatabase.GetAllAssetPaths();
foreach(var assetPath in allAssetPaths)
{
if ( System.IO.Path.GetExtension(assetPath).ToLower() != ".prefab")
{
continue;
}
if (!InFindPath(assetPath))
{
continue;
}
string fname = System.IO.Path.GetFileNameWithoutExtension(assetPath).ToLower().Trim();
if (fname == assetName)
{
return assetPath;
}
}
return string.Empty;
}
private static GameObject ReplaceGo(GameObject sobj)
{
var pos = sobj.transform.position;
var rot = sobj.transform.rotation;
var parentObj = sobj.transform.parent;
if (parentObj == null)
{
return null;
}
var sindex = sobj.transform.GetSiblingIndex();
var sname = sobj.name.Trim();
for(int i=30; i>=0; i--)
{
sname = sname.Replace("(" + i.ToString() + ")", "");
}
sname = sname.ToLower().Trim();
var findAssetPath = FindAsset(sname);
if (string.IsNullOrEmpty(findAssetPath))
{
Log.Warning("没有找到匹配的资源:{0}", sname);
return null;
}
var prefabTemplate = AssetDatabase.LoadAssetAtPath<GameObject>(findAssetPath);
if (prefabTemplate == null)
{
Log.Warning("载入失败1:{0}", findAssetPath);
return null;
}
var newObj = PrefabUtility.InstantiatePrefab(prefabTemplate) as GameObject;
if (newObj == null)
{
Log.Warning("载入失败2:{0}", findAssetPath);
return null;
}
newObj.transform.SetParent(parentObj, false);
newObj.transform.position = pos;
newObj.transform.rotation = rot;
newObj.transform.SetSiblingIndex(sindex);
Undo.RegisterCreatedObjectUndo(newObj, "created rig");
Log.Logic("<color=blue>替换成功: {0} -> {1}</color>", sname, findAssetPath);
return newObj;
}
[MenuItem("GameObject/UwMapEditor/替换为Prefab %#V")]
static public void ReplacePrefab()
{
var sobj = Selection.gameObjects;
if ( sobj == null || sobj.Length == 0)
{
return;
}
List<GameObject> delObjs = new List<GameObject>();
List<GameObject> addObjs = new List<GameObject>();
for(int i=0; i<sobj.Length; ++i)
{
var addObj = ReplaceGo(sobj[i]);
if (addObj != null)
{
addObjs.Add(addObj);
delObjs.Add(sobj[i]);
}
}
foreach(var obj in delObjs)
{
Undo.DestroyObjectImmediate(obj);
}
Selection.objects = addObjs.ToArray();
foreach(var obj in addObjs)
{
UnityEditor.EditorUtility.SetDirty(obj);
}
}
}
CopyRights: The Post by BY-NC-SA For Authorization,Original If Not Noted,Reprint Please Indicate From 老刘@开发笔记
Post Link: [Unity]自动将断链的Prefab替换为真Prefab
Post Link: [Unity]自动将断链的Prefab替换为真Prefab