為Unity元件編寫擴充套件

敲鍵盤的貓發表於2019-02-16

最近遇到一個需求,需要快速獲取一個GameObject在Hierarchy皮膚中的路徑。在谷歌上左搜右搜,就是找不到,使用的關鍵詞是Hierarchy、GameObject、Path、Relationship等。後來想起來,前幾天在宣雨鬆的微博上看到一個小Tip,附上連結,再次感謝雨鬆大大。

這幾行程式碼,寫到一個Editor檔案中,就可以在滑鼠選中某個遊戲物件時,列印出它的路徑,Let me show you the code!

using UnityEngine;
using UnityEditor;
using System.Collections;

public class ToolKit : EditorWindow {

    // Use this for initialization
    [InitializeOnLoadMethod]
    static void Start () {
        Selection.selectionChanged = delegate {
            Debug.Log(Selection.activeGameObject.transform.GetPath());
            //這裡我做了改動
        };
    }
}

紫薇請等一下!=ε=ε=ε=┏(゜ロ゜;)┛
為什麼我這裡沒有GetPath()函式呀?
嚯嚯嚯,這個是我的擴充套件啦!

我曾經大量使用列舉的擴充套件函式,比如我需要用列舉定義所有的技能,每個技能有一個名稱,我一般寫成擴充套件。

public enum Skill{
    Fuck
}

static class SkillMethods{
    public static string GetName(this Skill type){
        return "我幹";
    }
}

這樣我需要的時候,直接用Skill.Fuck.GetName()就可以啦,我自己覺得蠻方便的……可維護性很強。

那麼再來看下GetPath函式的需求,雖然Transform不能獲取路徑,但是可以找到父節點,還可以找到root,這就很方便啦,只要從底向上,把所有名字用連線起來就可以了~自己動手豐衣足食吶!

上程式碼!

public static class TransformExtension {
    public static string GetPath(this Transform trans){
        Transform current = trans;
        StringBuilder path = new StringBuilder(current.name);

        while(true){
            if(current != trans.root){
                current = current.parent;
                path.Insert(0, current.name + "/");
            }else{
                break;
            }
        }

        return path.ToString();
    }
}

有幾個地方需要解釋給第一次寫擴充套件的人說說。

  1. 擴充套件的格式就是如此,元件名加上Extension字尾,和列舉的擴充套件方法不同。裡面的函式名、變數之類的,也要按照我程式碼中的格式來寫。

  2. StringBuilder是推薦的字串拼接方式,需要using System.Text;,可以提升字串拼接效能,如果大量操作,用+號可能會有卡頓哦~我這裡雖然沒有大量操作,但是為了使用Insert函式就用了StringBuilder。

  3. Insert這裡是為了將父節點的名字,插在路徑前面,因為我們是從底向上找,但是最終結果需要的是父節點在前,子節點在後的字串。

  4. 用一個指標指向當前節點,如果不是根節點,那麼將父節點指向為當前節點,並拼接名字,然後用迴圈一直找到root節點為止。

就醬!

相關文章