Unity获取游戏对象详解(来自我的长微博)

转载 自 雨松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

转载 雨松mono Unity获取游戏对象详解(来自我的长微博)相关推荐

  1. unity获取游戏对象及修改游戏对象的属性,对于游戏对象的基本操作

    一:unity获取游戏对象 1直接获取 2通过路径获取 3创建函数体 4根目录开始获取.先上后先获取 1.GameObject.Find只能发现激活的对象 2.transform.Find可以发现未激 ...

  2. Unity3D获取游戏对象组件的三种方式

    Unity获取游戏对象组件的三种方式 用Find查询 1. GameObejct go = GameObject.Find("对象名").GetComponent<获取对象上 ...

  3. Unity中获取游戏对象的组件

    本文转载自Unity 得到游戏组件的常用的两种方法 常用的获取游戏对象组件的方法 获取当前挂载游戏对象的组件 index = this.GetComponent<******>(); // ...

  4. Unity查找游戏对象及组件

    一.访问游戏对象自身的游戏组件 GetComponent<T>(); //T为组件名称   GetComponents<T>();   transform.Translate( ...

  5. 《Android游戏开发详解》一2.18 使用Java API中的对象

    本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.18节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2.1 ...

  6. 《Android游戏开发详解》一2.16 区分类和对象

    本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.16节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社 ...

  7. 《Android游戏开发详解》——第2章,第2.13节调用对象的行为

    本节书摘来自异步社区<Android游戏开发详解>一书中的第2章,第2.13节调用对象的行为,作者 [美]Jonathan S. Harbour,更多章节内容可以访问云栖社区"异 ...

  8. 「翻译」Unity中的AssetBundle详解(一)

    AssetBundles AssetBundle是一个存档文件,其中包含平台在运行时加载的特定资产(模型,纹理,预制,音频剪辑,甚至整个场景).AssetBundles可以表示彼此之间的依赖关系;例如 ...

  9. JavaScript对象详解

    转载请注明预见才能遇见的博客:https://my.csdn.net/ 原文地址:https://blog.csdn.net/weixin_42787326/article/details/81297 ...

最新文章

  1. sublime text3 怎么配置、运行python_怎么用sublime text 3搭建python 的ide?
  2. 宕机的阿里云们正在杀死运维?
  3. .Net 自定义应用程序配置
  4. 网络报文的数据格式定义和使用
  5. OpenCASCADE:OCCT应用框架OCAF之TObj模型对象
  6. android 抓取webview中的所有图片_如何一键提取PDF文档中的所有图片?
  7. 三星Galaxy Z Fold3定档8月11日:售价预计将超1.5W
  8. 安装centos7步骤_Centos7下源码编译安装mysql5.7 详细步骤 小白也能安装
  9. [转载] 浅析Java中volatile关键字及其作用
  10. 程序执行系统VC++程序出现“试图执行系统不支持的操作”
  11. JS中时间格式化常用方法
  12. 2005开启服务器文件夹,vss2005图文教你如何安装与配置?
  13. localhost改成想要的IP方法
  14. 企业微信在线客服机器人系统开发
  15. linux 多核 双系统,Linux GRUB实现双系统引导教程
  16. 公告栏模板php代码,如何实现手机端公告栏显示
  17. Pthon画皮卡丘源码
  18. Ajax Interceptor工具分享
  19. Python实现word文档的字数统计
  20. Fabric链码实战(二)公民身份信息

热门文章

  1. 使用 apiDoc 为你的Node.js API 生成文档
  2. CMake 构建项目Android NDK项目基础知识
  3. vim编辑器的使用--转自MJ学长
  4. Windows Server 2008 RemoteApp---发布应用程序
  5. Apache的认证、授权、访问控制
  6. 基于GDAL库,读取海洋风场数据(.nc格式)c++版
  7. Java 集合练习——3
  8. sql server 之函数小技巧 整数类型为空是用空字符串替代实现
  9. border:none 与border:0的区别
  10. Horspool 字符串快速查找算法