Unity插件開發:PrefabUtility(一)--Prefab實例引用斷開和引用替換

    在Unity使用Prefab過程當中,咱們有時候須要進行Prefab實例斷開引用和替換引用的需求。實現這些需求,使用到的核心的類是PrefabUtility。PrefabUtility是一個靜態類,主要用於進行Prefab的相關處理。 這裏主要使用如下幾種方法html

  • PrefabUtility.CreateEmptyPrefab
  • PrefabUtility.ReplacePrefab
  • PrefabUtility.DisconnectPrefabInstance
  • PrefabUtility.GetPrefabParent
  • PrefabUtility.ConnectGameObjectToPrefab

斷開引用

    斷開Prefab引用的代碼以下函數

[MenuItem("Tools/Prefab/去除引用")]ui

public static void BreakPrefabRef()spa

{code

    var select = Selection.activeGameObject;orm

    if (select.activeInHierarchy)htm

    {blog

        PrefabUtility.DisconnectPrefabInstance(select);ip

        Selection.activeGameObject = null;內存

        var prefab = PrefabUtility.CreateEmptyPrefab("Assets/empty.prefab");

        PrefabUtility.ReplacePrefab(select, prefab, ReplacePrefabOptions.ConnectToPrefab);

        PrefabUtility.DisconnectPrefabInstance(select);

        AssetDatabase.DeleteAsset("Assets/empty.prefab");

    }

}

    雖然PrefabUtility.DisconnectPrefabInstance有斷開Prefab的含義,可是若是僅僅使用這個函數會出現下面這個狀況,名字的顏色從藍變白,看起來已經不是一個prefab,可是從Inspector面板中仍是可以看到Prefab標記以及Prefab實例纔會出現的那三個Select、Revert、Apply按鈕。

2017110201

    若是嘗試在這個時候刪除掉Project裏面的源prefab,發現這個prefab標記就消失了。

    所以,這裏採用如下方法實現整個斷開引用

  • 使用Selection.activeGameObject獲取當前選中的物體
  • 使用PrefabUtility.CreateEmptyPrefab先建立一個空的prefab
  • 使用PrefabUtility.ReplacePrefab將場景中選中的Prefab實例製做成一個Prefab並覆蓋到以前的空prefab上
  • 使用PrefabUtility.DisconnectPrefabInstance斷開引用
  • 使用AssetDatabase.DeleteAsset刪除Project中新建的prefab

    至此就完成了斷開引用的功能。這裏在函數加上[menuitem]標籤,將這個功能放在unity菜單「Tools->Prefab->去除引用」上。

替換引用

    替換引用的代碼以下

[MenuItem("Tools/Prefab/替換引用")]

public static void RelocalPrefabRef()

{

    var select = Selection.activeGameObject;

    if (select.activeInHierarchy)

    {

        var ab = PrefabUtility.GetPrefabParent(select);

        if (ab == null)

            return;

        var oripath = AssetDatabase.GetAssetPath(ab);

        var filters = new[] { "prefab file", "prefab" };

        var tar = EditorUtility.OpenFilePanelWithFilters("select target", Application.dataPath, filters);

        if (string.IsNullOrEmpty(tar))

            return;

        tar = FileUtil.GetProjectRelativePath(tar);

        var tarprefab = AssetDatabase.LoadAssetAtPath<GameObject>(tar);

        if (tarprefab == null)

            return;

        var gname = select.name;

        var enable = select.activeInHierarchy;

        var pos = select.transform.localPosition;

        var rot = select.transform.localRotation;

        var scale = select.transform.localScale;

        var go = PrefabUtility.ConnectGameObjectToPrefab(select, tarprefab);

        go.transform.localPosition = pos;

        go.transform.localRotation = rot;

        go.transform.localScale = scale;

        go.name = gname;

        go.SetActive(enable);

        Debug.LogFormat("Replace Prefab From:{0} to {1}", oripath, tar);

    }

}

    代碼中主要的流程爲

  • 使用Selection.activeGameObject獲取選中的物體
  • 使用PrefabUtility.GetPrefabParent獲取這個物體在project中的源prefab
  • 使用AssetDatabase.GetAssetPath獲取源prefab在project中的路徑(後面用於log)
  • 使用EditorUtility.OpenFilePanelWithFilters打開一個文件選擇窗口讓玩家選擇一個源prefab
  • 使用FileUtil.GetProjectRelativePath獲取這個源prefab相對於工程的路徑
  • 使用將這個源prefab加載到內存中
  • 爲了保持替換後的位置關係,這裏記錄了原來的位置信息
  • 使用PrefabUtility.ConnectGameObjectToPrefab從新將選中的物體連接到玩家選擇的源prefab上,完成prefab引用替換
  • 還原原來的位置關係

    至此完成了Prefab實例替換引用的功能。在Unity中選擇菜單Tools->Prefab->替換引用,選擇一個prefab便可實現替換

轉載保留:http://www.cnblogs.com/CodeGize http://www.codegize.com

相關文章
相關標籤/搜索