站长之家psd,阳江网红桥定位,东莞专业营销网站建设推广,网站安全建设总结报告Unity获取游戏对象详解#xff08;来自我的长微博#xff09; 转载 自 雨松mono 本文固定链接: http://www.xuanyusong.com/archives/2768转载请注明: 雨松MOMO 2014年06月16日 于 雨松MOMO程序研究院 发表我觉得Unity里面的Transform 和 GameObject就像两个双胞胎兄弟一样来自我的长微博 转载 自 雨松mono 本文固定链接: http://www.xuanyusong.com/archives/2768转载请注明: 雨松MOMO 2014年06月16日 于 雨松MOMO程序研究院 发表 我觉得Unity里面的Transform 和 GameObject就像两个双胞胎兄弟一样这俩哥们很要好我能直接找到你你也能直接找到我。我看很多人喜欢在类里面去保存GameObject对象。解决GameObject.Find()无法获取天生activie false的问题。 private GameObject root ; 我觉得你最好不要保存GameObject 而是去保存Transform 因为Transform下的方法要比GameObject多使用频率也要高很多。 private Transform root ; 其实我心里一直有个疑问为什么unity不把GameObject和Transform合并成一个对象。 1.GameObject.Find() 通过场景里面的名子或者一个路径直接获取游戏对象。 GameObject root GameObject.Find(“GameObject”); 我觉得如果游戏对象没再最上层那么最好使用路径的方法因为有可能你的游戏对象会有重名的情况路径用“/”符号隔开即可。 GameObject root GameObject.Find(“GameObject/Cube”); GameObject.Find()使用起来很方便但是它有个缺陷如下图所示就是如果你的这个GameObject天生acive false的话。那么你用GameObject.Find()是永远也无法获取它的对象的。如果对象都获取不到那么对象身上脚本啊 组件啊啥的都是获取不到的变成了没有意义的对象。 就这个问题我查过很多资料最终也无果。。但是我用另外一个巧妙的办法可以解决它。后面详解或者你也可以提前把所有的游戏对象保存在内存中。 GameObject.Find()方法在游戏中的使用频率很高。但是它也很消耗性能你可以想想它的原理肯定也是用类似递归的形式来做的那么我们就要尽量更少的调用GameObject.Find()方法可以把获取的游戏对象保存在内存里这是再好不过的选择了。 尤其是在Update方法中不要去 Find()游戏对象 2 .Transform.Find() 还记得上面我说过用GameObject无法获取天生acive false的游戏对象如果你用Transform.Find()的话就可以很好的获取另外Unity还提供了一个Transform.FindChind()的方法这个方法未来会被unity废弃大家最好就别用了用Transform.Find()可以取代。 如下代码我们先获取顶级对象root 。接着用Find()去找它的子节点”xxxx”的对象无论”xxxx”对象是否active true 都是可以直接找到对象的。 C# 1 2 3 4 GameObject root GameObject.Find(GameObject); GameObject xxxx root.transform.Find(xxxx).gameObject; xxxx.SetActive(true); Find()方法只能直接去找子节点如果你想找 孙节点那么可以用”/“符号把层级关系隔开找起来很方便。同样无论”xxxx”对象是否active true 都是可以直接找到对象的。 C# 1 GameObject cube root.transform.Find(xxxx/Cube).gameObject; 值得注意的是unity规定了比如父节点active true 并且子节点的 active true 都满足的情况下 才能全部显示。使用Transform.Find()可以很方便的获取游戏对象因为有了游戏对象那么它身上的脚本啊组件啊什么的都可以很方便的获取到。 但是Transform.Find()必须要保证你的顶级父对象的activity true。举个例子你做了一个场景有一些地图你在场景里面预先activie false了 你希望在游戏中的某个时间点把它们都打开 setActive(true) 你可以把“map”节点放在一个active true的GameObject上无论是关闭 或者 显示 代码中写起来都很方便。 假如你的map节点就是顶级节点那么它一旦天生acive false 那么你将无法得到它的对象更无法设置它的属性了。 GameObject root GameObject.Find(“GameObject”); GameObject map root.transform.Find(“map”).gameObject; map.SetActive(true); 3. unity 还提供了几个获取游戏对象的方法但是我个人觉得使用频率不高这里也简单说两句。 GameObject.FindGameObjectsWithTag(“tag”) GameObject.FindWithTag(“tag”) 根据一个标记来获取游戏对象返回一个 或者 一个数组我个人觉得这个两个方法没啥用因为既然需要用到标记那么相比这个游戏对象必然是非常特殊的一个所以我会把它存在内存中。 Object.FindObjectOfType Object.FindObjectsOfType Resources.FindObjectsOfTypeAll 根据一个类型返回Object比如 GameObject 、Texture、Animation 、甚至还可以是你自己写的一个脚本 的范型。它找起来很方便可以返回一个 或者一个数组。 我觉得这几个方法其实游戏中也没啥用不过在编辑器中使用的确实很频繁比如你要做批量检查场景的工具查找场景中有没有使用某个特殊类型的对象。 或者查看内存的占用量看看当前内存中那些Texture没有被释放掉。 等等。 还有一个方法如果你知道自对象的索引还可以用下面的方法来获取参数是index的索引。 transform.GetChild(0) 找到了一个即使隐藏root节点gameObject也能进行查找的方法。http://answers.unity3d.com/questions/52560/gameobjectfind-work-on-inactive-objects.html C# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 GameObject[] pAllObjects (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject)); foreach (GameObject pObject in pAllObjects) { if (pObject.transform.parent ! null) { continue; } if (pObject.hideFlags HideFlags.NotEditable || pObject.hideFlags HideFlags.HideAndDontSave) { continue; } if (Application.isEditor) { string sAssetPath AssetDatabase.GetAssetPath(pObject.transform.root.gameObject); if (!string.IsNullOrEmpty(sAssetPath)) { continue; } } Debug.Log(pObject.name); } 转载于:https://www.cnblogs.com/dudu580231/p/6627768.html