【Unity游戏开发之四】GameObject.Find()、Transform.Find查找隐藏对象

  • GameObjectFindTransformFind查找游戏对象

    • 前置条件
    • 相关API
      • 1 GameObjectFind
      • 2 TransformFind
      • 3 其他查找
    • 实际测试
    • 即使隐藏root节点gameObject也能进行查找的方法

GameObject.Find()、Transform.Find查找游戏对象

1.前置条件

Unity中常用到查找对象,非隐藏的、隐藏的,各种方法性能有高有低,使用又有各种条件限制。

在此对查找的性能和条件进行分析。开发时遇到的主要问题是查找隐藏对象。

没有完美的查找方法,只有最合适的查找方法

最后附带上测试代码

2.相关API

GameObject.Find

Transform.Find

GameObject.FindWithTag

GameObject.FindGameObjectsWithTag

Resources.FindObjectsOfTypeAll

2.1 GameObject.Find

通过名字或路径查找游戏对象。

GameObject.Find("GameObject");
GameObject.Find("GameObject/ChildGameObject);

使用规范:

1.无法查找隐藏对象

隐藏对象包括查找路径的任何一个父节点隐藏(active=false)

2.如果查找不在最上层,建议合理使用路径查找,路径查找是把双刃剑

优点1:解决查找中可能出现的重名问题。

优点2:如果有完全的路径,减少查找范围,减少查找时间。

缺点: 路径或结构调整后,容易影响到程序中的查找,需要重新定位查找路径。

3.如果路径查找中的任何一个父节点active=false,这个对象都将查找不到。

4.使用方便但效率低下

此查找相当于递归遍历查找,虽使用方便但效率堪忧,建议在Start()函数中查找对象并保存引用,切忌在Update()中动态查找。

2.2 Transform.Find

1.可以查找隐藏对象

2.支持路径查找

3.查找隐藏对象的前提是transform所在的根节点必须可见,即active=true

GameObject root = GameObject.Find("root");
root.SetActive(false); // 根节点为空

// 总是查找失败
root.transform.Find("root/AnyChildObjectName");

实际开发:

实际开发中会将功能预制体放到一个可见的GameObject目录下,将这个GameObject目录作为查找根节点,下面的所有对象(隐藏、非隐藏)都可以查找到。

你可以把”map”节点放在一个active = true的MapRoot上,无论是关闭 或者 显示 代码中写起来都很方便。 假如你的map节点就是顶级节点,那么它一旦天生acive = false ,那么你将无法得到它的对象,更无法设置它的属性了。

GameObject root = GameObject.Find("MapRoot");

GameObject map =  root.transform.Find("map").gameObject;
map.SetActive(true);

2.3 其他查找

GameObject.FindWithTag

GameObject.FindGameObjectsWithTag

使用极少,并无卵用

Resources.FindObjectsOfTypeAll

返回指定类型的对象列表。主要用于编辑器中,eg。检测内存泄露、批量查找的功能等

3 实际测试

目录结构如下,绿色代表现实,红色代表隐藏

void Start () {
    // GameObject.Find
    {
        // 根节点
        GameObject.Find("A11");     // true

        // 父节点(受父节点影响)
        GameObject.Find("A21");     // false
        GameObject.Find("A22");     // true

        // 孙子节点(受父节点影响)
        GameObject.Find("A31");     // false
        GameObject.Find("A32");     // false
        GameObject.Find("A33");     // false
        GameObject.Find("A34");     // true

        GameObject.Find("A34");                 // true  相对路径查找
        GameObject.Find("/A34");                // false 绝对路径查找
        GameObject.Find("/A11/A22/A34");        // true
        GameObject.Find("A11/A22/A34");         // true
        GameObject.Find("/A22/A34");            // false
        GameObject.Find("A22/A34");             // true
    }

    // Transform.find
    {
        // 根节点
        Transform A11 = transform.Find("A11");      // false

        // 父亲节点
        Transform A21 = transform.Find("A21");      // true
        Transform A22 = transform.Find("A22");      // true

        // 孙子节点
        Transform A31 = transform.Find("A31");      // false
        Transform A32 = transform.Find("A32");      // false
        Transform A33 = transform.Find("A33");      // false
        Transform A34 = transform.Find("A34");      // false

        // 使用相对于根节点的查找目录
        Transform AA31 = transform.Find("A21/A31");     // true
        Transform AA32 = transform.Find("A21/A32");     // true
        Transform AA33 = transform.Find("A22/A33");     // true
        Transform AA34 = transform.Find("A22/A34");     // true

        // 包含根节点的查找目录
        Transform AA311 = transform.Find("A11/A21/A31");        // false
        Transform AA321 = transform.Find("A11/A21/A32");        // false
        Transform AA331 = transform.Find("A11/A22/A33");        // false
        Transform AA341 = transform.Find("A11/A22/A34");        // false

        // 绝对路径
        Transform AA3111 = transform.Find("/A11/A21/A31");      // false
        Transform AA3211 = transform.Find("/A11/A21/A32");      // false
        Transform AA3311 = transform.Find("/A11/A22/A33");      // false
        Transform AA3411 = transform.Find("/A11/A22/A34");      // false
    }
}

4 即使隐藏root节点gameObject也能进行查找的方法

找到了一个即使隐藏root节点gameObject也能进行查找的方法。

http://answers.unity3d.com/questions/52560/gameobjectfind-work-on-inactive-objects.html

代码预览:


        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);
         }

参考文章:雨凇Unity获取游戏对象详解

http://www.xuanyusong.com/archives/2768

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-25 11:52:01

【Unity游戏开发之四】GameObject.Find()、Transform.Find查找隐藏对象的相关文章

unity3D中GameObject.Find()、Transform.Find查找隐藏对象分析(转)

GameObject.Find().Transform.Find查找游戏对象 1.前置条件 Unity中常用到查找对象,非隐藏的.隐藏的,各种方法性能有高有低,使用又有各种条件限制. 在此对查找的性能和条件进行分析.开发时遇到的主要问题是查找隐藏对象. 没有完美的查找方法,只有最合适的查找方法 最后附带上测试代码 2.相关API GameObject.Find Transform.Find GameObject.FindWithTag GameObject.FindGameObjectsWith

Unity 游戏开发技巧集锦之使用cookie类型的纹理模拟云层的移动

Unity 游戏开发技巧集锦之使用cookie类型的纹理模拟云层的移动 使用cookie类型的纹理模拟云层的移动 现实生活中,当阳光直射大地,而天空中又有很多云时,云层的影子总是会投射在大地上,风吹着云层移动,影子也跟着运动,如图3-28所示. 图3-28  天空中的云朵与大地上的影子 要在游戏中,模拟与之类似的大气现象时,就需要使用cookie类型的纹理. 制作云层效果的纹理 本小节将使用PhotoShop绘制有云层效果的纹理图,然后为其添加透明度信息.具体操作过程如下: (1)使用Photo

?Unity 游戏开发技巧集锦之使用忍者飞镖创建粒子效果

Unity 游戏开发技巧集锦之使用忍者飞镖创建粒子效果 使用忍者飞镖创建粒子效果 游戏中,诸如烟.火.水滴.落叶等粒子效果,都可以使用粒子系统(particle system)来实现.例如,<明朝传奇>中的篝火,如图2-32所示.粒子系统的最新版本也被称做忍者飞镖(Shuriken),因为场景中添加的粒子系统酷似忍者飞镖,如图2-33所示. 图2-32  游戏中的篝火               图2-33  粒子系统,也被称为忍者飞镖 unity中粒子基本属性 在使用粒子系统前,先了解一下它

Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机

Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机 Unity中制作一个望远镜 本节制作的望远镜,在鼠标左键按下时,看到的视图会变大:当不再按下的时候,会慢慢缩小成原来的视图.游戏中时常出现的狙击手就是使用望远镜的一个例子,如图2-22所示.   图2-22  游戏中狙击手所看到的视图 制作望远镜的过程如下: (1)在Project视图里,创建一个C#脚本文件,命名为TelescopicView.打开这个脚本文件,并在里面添加下面的代码: 01     using UnityEngine

【Unity游戏开发】不接SDK也能在游戏内拉起加QQ群操作?

一.引子 一般在游戏进行对外测试的时候都会有一个玩家QQ群,方便玩家反馈问题.交流游戏心得等.那么为了增加玩家加QQ群的欲望,可能会在游戏里面设计一个小功能,点击一下可以直接拉起手Q加群的操作,加了QQ群以后,也会自动下发一些小奖励刺激玩家.原本我以为要拉起手Q加QQ群的操作一定要接入相关平台的SDK才行,直到我详细地阅读了下腾讯官网的QQ群官方主页,我才了解到在游戏内拉起手Q发起加群的操作是如此的简单,根本不需要接入任何第三方SDK,只需短短几行代码即可轻松实现.闲言少叙,书归正文,咱们马上就

C# Unity游戏开发——Excel中的数据是如何到游戏中的 (二)

本帖是延续的:C# Unity游戏开发——Excel中的数据是如何到游戏中的 (一) 上个帖子主要是讲了如何读取Excel,本帖主要是讲述读取的Excel数据是如何序列化成二进制的,考虑到现在在手游中应用很广泛的序列化技术Google的ProtoBuf,所以本文也是按照ProtoBuf的方式来操作的.ProtoBuf是一个开源库,简单来说ProtoBuf就是一个能使序列化的数据变得更小的类库,当然这里指的更小是相对的.好了ProtBuf的东西就不在多说,以后会专门写一篇帖子的.本帖其实就相当于上

C# Unity游戏开发——Excel中的数据是如何到游戏中的 (三)

本帖是延续的:C# Unity游戏开发——Excel中的数据是如何到游戏中的 (二) 前几天有点事情所以没有继续更新,今天我们接着说.上个帖子中我们看到已经把Excel数据生成了.bin的文件,不过其实这样到游戏中还是不能用的.主要有两个方面,1.bin文件的后缀使我们随便取的名字,但是这种文件Unity不买账.因为Unity中的二进制文件必须是以.bytes命名的.2.在写文件之前其实还可以对二进制进行压缩,这样可以最大化节省设备空间.也就是说我们在生成数据实例后还需要做以下几件事:序列化 -

【CocoStudio游戏开发之四】UI.json 图片国际化

cocos2dx 3.0 CocoStudio1.4.1 做界面的时候用到了CocoStudio生成的UI.json文件,需要做语言本地化,论坛中有朋友给出了方法: 将本地化的图片设定格式,英文的叫button_store_normal.en.png 中文的叫button_store_normal.zh.png ...... 按照这种规则,根据需要的语言来加载不同的图片 我们用到的是另一种方法: 修改json文件,这里并不是真正的修改json文件,只是在读取json文件到内存后,不是立即交予GU

Unity 游戏开发技巧集锦之创建透明的材质

Unity 游戏开发技巧集锦之创建透明的材质 Unity创建透明的材质 生活中不乏透明或者半透明的事物.例如,擦的十分干净的玻璃,看起来就是透明的:一些塑料卡片,看起来就是半透明的,如图3-23所示.在Unity中,可以创建模拟了透明效果的材质,这也是本节主要讲解的内容. 图3-23  半透明的卡片 Unity创建并配置材质 在Project视图里,创建一个材质,并命名为TransMaterial,选中它然后在Inspector视图里修改Shader属性为Transparent/Diffuse,