这篇文章主要介绍了Unity如何给物体添加多个Tag,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
在unity中,我们经常通过给物体添加标签来判断这个物体是不是我们想要的
但是unity默认只能添加一个标签,那如果我们要给一个物体添加多个标签应该怎么办
首先,我们定义一个Tag.cs
类,这个类用来存储物体的tag信息
public class Tags : MonoBehaviour{ public List<string> tags=new List<string>();}
然后创建一个单例类TagManager.cs
用来管理tag
public class TagManager : MonoBehaviour { public static TagManager Instance { get; private set; } private void Awake() { if (Instance == null) { Instance = (TagManager) this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } }}
在TagManager
中增加存储tag的list和对应物体的dictionary
public List<string> tagsList = new List<string>();[ShowInInspector]public Dictionary<string, List<GameObject>> tagsDictionary = new Dictionary<string, List<GameObject>>();
但是inspector窗口中修改dictionary中的值后,播放时会自动清除数据,所以还要给dictionary赋值
private void InitTags() { int length = tagsList.Count; tagsDictionary = new Dictionary<string, List<GameObject>>(length); for (int i = 0; i < length; i++) { tagsDictionary.Add(tagsList[i], new List<GameObject>()); }}
然后我们通过在inspector窗口修改list来修改物体的taf
新建一个Extensions.cs
,我们在这个类里面写一些扩展方法
public static class Extensions { //包含所有的 tag 返回true public static bool HasTag(this GameObject gameObject, params string[] tag) { if (gameObject.TryGetComponent<Tags>(out Tags t)) { for (int i = 0; i < tag.Length; i++) { if (!t.tags.Contains(tag[i])) { Debug.Log(gameObject.name+"不存在"+tag+"标签"); return false; } } } return true; } //给物体增加 tag public static void AddTag(this GameObject gameObject, params string[] tags) { if (gameObject.TryGetComponent<Tags>(out Tags t)) { foreach (var tag in tags) { if (!TagManager.Instance.tagsList.Contains(tag)) { Debug.Log("增加一个tag:" + tag); TagManager.Instance.tagsDictionary.Add(tag, new List<GameObject>()); Debug.Log(tag + "增加一个物体" + gameObject.name); TagManager.Instance.tagsDictionary[tag].Add(gameObject); } else { Debug.Log(tag + "增加一个物体" + gameObject.name); TagManager.Instance.tagsDictionary[tag].Add(gameObject); } } } } //给物体删除tagpublic static void RemoveTag(this GameObject gameObject,params string[] tags) {for (int i = 0; i < tags.Length; i++) {if (gameObject.HasTag(tags[i])) {gameObject.GetComponent<Tags>().tags.Remove(tags[i]);Debug.Log(gameObject.name+"移除"+tags+"标签");TagManager.Instance.tagsDictionary[tags[i]].Remove(gameObject);}else {Debug.LogWarning(gameObject.name+"不存在"+tags[i]+"标签");}}}}
这样像下面这样直接调用即可
gameObject.AddTag("Player","Tag1");gameObject.HasTag("Player","Tag1");gameObject.RemoveTag("Player");
最后TagManager.cs
中通过标签获取所有物体
public List<GameObject> FindObjsWithTag(string tag) { if (tagsDictionary.ContainsKey(tag)) { return tagsDictionary[tag]; } Debug.Log("不存在标签为" + tag + "的物体"); return null;}
测试一下
创建两个挂有Tags.cs
脚本的物体
public class Tags : MonoBehaviour{ public List<string> tags=new List<string>(); void Start() { gameObject.AddTag(tags.ToArray()); gameObject.HasTag("Player"); } void Update(){ if (Input.GetKeyDown(KeyCode.A)) { gameObject.RemoveTag("Player","tag1"); } }}
两个物体具有的tag
分别为tag1
,tag2
和tag1
TagManager
只有tag1
运行
但是这样当退出Play模式后,List中的数据会被清空,所以可以使用ScriptableObject
进行持久化存储也可以使用Odin等插件直接对字典进行序列化
使用ScriptableObject
新建一个TagsAsset.cs
[CreateAssetMenu]public class TagsAsset : ScriptableObject{ public List<string> tags=new List<string>();}
将原先代码中tagsList
相关的代码修改为tagsAsset.tags
并修缮一下即可
使用Odin
导入Odin插件,使TagManager
继承自SerializedMonoBehaviour
[NonSerialized, OdinSerialize]public Dictionary<string, List<GameObject>> tagsDictionary = new Dictionary<string, List<GameObject>>();
感谢你能够认真阅读完这篇文章,希望小编分享的“Unity如何给物体添加多个Tag”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!