unity 一键应用多个预制体
当我们在预制体上做了修改后,如果想要把修改应用到asset中存储的prefab中,就需要进行应用:
而如果同时需要应用的prefab太多的话,比方说有几十上百个,这种一个一个应用的方法就会很累人,我们可以写一个脚本来帮助我们做这件事,话不多说,先放代码:
[MenuItem("TimelineTools/应用选中预制体")]
private static void ApplySelectedPrefabs()
{
GameObject[] selectedGameobjects = Selection.gameObjects;
for(int i = 0; i < selectedGameobjects.Length; i++)
{
GameObject obj = selectedGameobjects[i];
//如果场景中的预制体实体和asset中的预制体连接
if(PrefabUtility.GetPrefabInstanceStatus(obj) == PrefabInstanceStatus.Connected)
{
//找到asset中对应存储的预制体
Object parentObject = PrefabUtility.GetCorrespondingObjectFromSource(obj);
string path = AssetDatabase.GetAssetPath(parentObject);
//将预制体实例应用到asset中存储的预制体上
PrefabUtility.SaveAsPrefabAssetAndConnect(obj, path, InteractionMode.UserAction);
AssetDatabase.Refresh();
}
}
}
这个脚本需要引用unityEditor,其中Selection.gameObjects即为我们当前选中的对象列表。
PrefabUtility.GetPrefabInstanceStatus这个函数用来判别一个物体的预制体状态,
用PrefabInstanceStatus枚举表示物体的状态,有已连接、未连接、丢失资源、不是预制体这几个状态选项,可以在unity PrefabUtility官方API上查询。
PrefabUtility.GetCorrespondingObjectFromSource的作用是找到预制体实例的资源位置,以便于后续更改。而PrefabUtility.SaveAsPrefabAssetAndConnect这个函数,根据官方上的解释,则是由给定路径创建一个预制体资源,以当前游戏对象的内容作为实例,也就是替换原来的预制体资源。
见API上的解释:
除了靠同时选中来执行操作外,我们还可以根据标签来进行预制体的应用,代码如下:
[MenuItem("TimelineTools/应用所有标记预制体")]
private static void ApplyMentionedPrefabs()
{
List<GameObject> mentionedPrefabs = FindObjects("prefab");
foreach(GameObject obj in mentionedPrefabs)
{
//如果场景中的预制体实体和asset中的预制体连接
if (PrefabUtility.GetPrefabInstanceStatus(obj) == PrefabInstanceStatus.Connected)
{
//找到asset中对应存储的预制体
Object parentObject = PrefabUtility.GetCorrespondingObjectFromSource(obj);
string path = AssetDatabase.GetAssetPath(parentObject);
//将预制体实例应用到asset中存储的预制体上
PrefabUtility.SaveAsPrefabAssetAndConnect(obj, path, InteractionMode.UserAction);
AssetDatabase.Refresh();
}
}
}
//根据tag在hierarchy里找到物体,包括隐藏的物体
private static List<GameObject> FindObjects(string tag)
{
List<GameObject> gameObjects = new List<GameObject>();
foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)))
{
if (!EditorUtility.IsPersistent(go.transform.root.gameObject) && !(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave))
{
if (go.tag == tag)
gameObjects.Add(go);
}
}
return gameObjects;
}
和上一个方法的区别就是添加了一个寻找方法,寻找到对应标签的游戏对象组,关于这个寻找的方法,可以参照我的另一篇博客:https://blog.csdn.net/weixin_43347688/article/details/107322746
本文地址:https://blog.csdn.net/weixin_43347688/article/details/107322813
上一篇: 小程序实现语音识别转文字,坑路历程