在unity中,tag是一個好東西,咱們能夠用tag來區分物體,也能夠經過tag來快速地查找物體。可是美中不足的是,tag是一個字符串string。爲何說美中不足呢?編輯器
由於假如咱們在一個腳本里面想要有一個Tag字段,都只能定義一個string字段。spa
using UnityEngine; public class TagObjFinder : MonoBehaviour { public string Tag; public GameObject[] FindGos { get; private set; } public void Start() { FindGos = GameObject.FindGameObjectsWithTag(Tag); } }
而這樣的話,在編輯器中,就很是不方便填寫,也很是容易出錯。code
有一些人會採用CustomEditor的方法,利用TagField能夠很是好地使用Tag下拉框。這種經過自定義屬性面板的方法其實並不同意,由於總不可能給每個須要用到tag的腳本都專門給它寫一個CustomEditor。blog
而第二個緣由是在代碼中使用了大量表示tag的string,很是不優雅,查找和維護都至關不方便。好比:常常看到GameObject.FindGameObjectsWithTag(「Player」)或者是if(gameObject.tag=="GameController」);這樣的代碼。字符串
那麼有人也想到辦法,就是手動定義,const全部的tag。好比get
public const string TagPlayer=」Player」;同步
public const string TagMainCamera=」MainCamera」;string
確實這是一個方法。經過查找const變量能夠找到全部的引用,很是方便。惋惜的是,在屬性面板中,依然須要手動填寫。it
既然const不行的話,是否是可使用枚舉呢?固然能夠,並且很是優雅。屬性面板中還能選擇,很是適合。io
public enum EmTag { Untagged, Respawn, Finish, EditorOnly, MainCamera, Player, GameController, }
咱們改寫一下TagObjFinder
using UnityEngine; public class TagObjFinder : MonoBehaviour { public EmTag Tag; public GameObject[] FindGos { get; private set; } public void Start() { FindGos = GameObject.FindGameObjectsWithTag(Tag.ToString()); } }
不過有一個麻煩的就是,若是我在unity中增長了一個tag,就須要增長在代碼中一個枚舉值。這時候,unity的易擴展性就發揮出來了,咱們徹底能夠自動生成這個EmTag枚舉的代碼。
using System.IO; using System.Text; using UnityEditor; using UnityEditorInternal; using UnityEngine; public class TagEnumGenarator : MonoBehaviour { [MenuItem("Tools/GenTagEnum")] public static void GenTagEnum() { var tags = InternalEditorUtility.tags; var arg = ""; foreach (var tag in tags) { arg += "\t" + tag + ",\n"; } var res = "public enum EmTag\n{\n" + arg + "}\n"; var path = Application.dataPath + "/Tool/EmTag.cs"; File.WriteAllText(path, res, Encoding.UTF8); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } }
經過InternalEditorUtility.tags獲取到unity中已有的全部tag,而後經過File.WriteAllText方法寫入到一個cs文件中,這裏把這個文件EmTag.cs放在了」Assets/Tool/」下。
編譯完成,ok。這樣只要增長tag的時候,點擊一下菜單上的Tools->GenTagEnum就能夠同步代碼了。而後愉快地拋棄string tag,快樂地使用enum tag。