在《Unity插件開發:PrefabUtility--Prefab實例引用斷開和替換》中咱們使用了PrefabUtility實現了Prefab實例的引用斷開和替換功能,如今咱們繼續使用PrefabUtility來實現場景中全部Prefab實例的Apply功能。html
在不少狀況下,咱們會在場景中修改Prefab實例,這些修改理應apply到Prefab上,可是有時候會忘記Apply,過後再去找,可能花費不少時間。或者在一些條件下,須要對場景中的一些Prefab實例進行批量修改。這時候也須要批量apply到Prefab上。app
遍歷場景中全部GameObject,若是是Prefab實例,找到這個Prefab實例的Prefab根節點(可能重複,因此這裏還須要過濾一下,避免重複處理),而後找到這個Prefab實例對應的Prefab,用場景中的這個物體制做一個Prefab替換掉原來的Prefab。函數
注意,上圖中Directional Light是場景中的根節點,而Ticket是Prefab根節點。工具
要完成這個功能,須要用到如下幾個函數:spa
[MenuItem("Tools/Prefab/ApplyAll")] public static void AllApply() { var prefabs = Object.FindObjectsOfType<GameObject>();//場景中全部GameObject var lst = new List<GameObject>();//用於避免重複的列表 foreach (var gameObject in prefabs)//遍歷 { var isprefab = PrefabUtility.GetPrefabType(gameObject);//物體的PrefabType if (isprefab != PrefabType.PrefabInstance)//不是Prefab實例 continue; var prefab = PrefabUtility.GetPrefabParent(gameObject);//沒有對應的Prefab(可能被刪除掉了) if (prefab == null) continue; //Debug.Log(prefab); var rt = PrefabUtility.FindPrefabRoot(gameObject);//物體的Prefab根節點 if (rt == null || lst.Contains(rt))//存在且不重複 continue; lst.Add(rt);//增長到列表中 //Debug.Log(rt.name); PrefabUtility.ReplacePrefab(rt, prefab);//實現替換達到Apply的目的 } }
以上還能夠增長一些過濾,好比沒有修改過的物體不須要作替換等等插件
直接在工具欄,Tools->Prefab->ApplyAll便可。code
轉載保留:http://www.cnblogs.com/CodeGize http://www.codegize.comhtm