在unity中,tag是一个好东西,我们可以用tag来区分物体,也可以通过tag来快速地查找物体。但是美中不足的是,tag是一个字符串string。为什么说美中不足呢?
因为假如我们在一个脚本里面想要有一个Tag字段,都只能定义一个string字段。
using UnityEngine;
public class TagObjFinder : MonoBehaviour
public string Tag;
public GameObject[] FindGos { get; private set; }
public void Start()
FindGos = GameObject.FindGameObjectsWithTag(Tag);
而这样的话,在编辑器中,就非常不方便填写,也非常容易出错。
有一些人会采用CustomEditor的方法,利用TagField可以非常好地使用Tag下拉框。这种通过自定义属性面板的方法其实并不赞成,因为总不可能给每一个需要用到tag的脚本都专门给它写一个CustomEditor。
而第二个原因是在代码中使用了大量表示tag的string,非常不优雅,查找和维护都相当不方便。比如:经常看到GameObject.FindGameObjectsWithTag(“Player”)或者是if(gameObject.tag=="GameController”);这样的代码。
那么有人也想到办法,就是手动定义,const所有的tag。比如
public const string TagPlayer=”Player”;
public const string TagMainCamera=”MainCamera”;
确实这是一个方法。通过查找const变量可以找到所有的引用,非常方便。可惜的是,在属性面板中,依然需要手动填写。
既然const不行的话,是不是可以使用枚举呢?当然可以,而且非常优雅。属性面板中还能选择,非常适合。
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());
(看起来和TagField的效果是一样的)
不过有一个麻烦的就是,如果我在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。
个人博客请访问:http://www.cnblogs.com/CodeGize/