Unity插件開發:PrefabUtility(二)--Prefab實例批量Apply

        在《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。函數

        image

        注意,上圖中Directional Light是場景中的根節點,而Ticket是Prefab根節點。工具

        要完成這個功能,須要用到如下幾個函數:spa

  • PrefabUtility.ReplacePrefab——替換Prefab
  • PrefabUtility.GetPrefabParent——獲取prefab
  • PrefabUtility.GetPrefabType——獲取一個物體的prefab類型
  • PrefabUtility.FindPrefabRoot——獲取一個物體在prefab(或prefab實例)中的根節點

實現

    [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

相關文章
相關標籤/搜索