Unity基础 之 查找游戏物体的几种方式解析(一)

1,541 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

前言:

一篇小白也能看懂的查找游戏物体的方式解析 -- Unity 之 查找物体的几种方式(一)。本文通过实际测试得出使用结论,大家进行简单记录,在使用时想不起来可以再来看看,多用几次基本就没有问题了。

一,Object.Find()

Object.Find():根据名称找到游戏对象并返回它。

void ObjectFind()
{
    // 找父级
    GameObject parent = GameObject.Find("GameObject");
    Debug.Log("找父级物体,是否找到:" + (parent != null));
    
    // 找子级
    GameObject child = GameObject.Find("Child");
    Debug.Log("找子级物体,是否找到:" + (child != null));
    
    // 找父级隐藏物体
    GameObject parentHide = GameObject.Find("GameObjectHide");
    Debug.Log("找父级隐藏物体,是否找到:" + (parentHide != null));
    
    // 找子级隐藏物体
    GameObject childHide = GameObject.Find("ChildHide");
    Debug.Log("找子级隐藏物体,是否找到:" + (childHide != null));
}

测试结果如下图: ObjectFind


当有使用GameObject.Find("GameObject"), 场景中有多个名为“GameObject”的物体存在时,将每个“GameObject”设置为不同的标签,多运行几次查看结果。

测试场景如下: 搭建场景

测试代码如下:

// 找同名物体
GameObject nameObj = GameObject.Find("GameObject");
Debug.Log("找同名,是否找到:" + nameObj.tag);

测试结果: 查找顺序是:“自身”(挂载脚本的物体) --> 和自身同层级上面物体 --> 和自身同层级下面物体 --> 自身子物体 --> 自身父物体。

找同名物体

Object.Find()得出结论:

  1. 全局查找参数名称游戏物体;
  2. 不对禁用(隐藏)物体进行查找;
  3. 若有同名物体时根据层级关系进行查找。

使用建议: 有同名物体存在时,尽量不要使用Object.Find()进行查找,或者说使用Object.Find()进行查找时,应控制查找物体命名唯一。


二,FindGameObjectWithTag()

GameObject.FindGameObjectWithTag() 根据标签查找游戏物体并返回。 GameObject.FindGameObjectsWithTag() 根据标签查找当前场景中所有这个标签的游戏物体并返回所有物体的数组。

将如下场景:除主摄像机~(Main Camera)外的所有游戏物体的标签(Tag)~都修改为Player,进行测试。

测试场景

测试代码如下:

void GameObjectFindWithTag()
{
    GameObject tagObj = GameObject.FindGameObjectWithTag("MainCamera");
    Debug.Log("根据标签查找游戏物体,是否查到:" + (tagObj != null));
    
    GameObject[] tagObjs = GameObject.FindGameObjectsWithTag("Player");
    for (int i = 0; i < tagObjs.Length; i++)
    {
        Debug.Log("根据标签查找游戏物体名称:" + tagObjs[i].name);
    }
}

测试结果:

测试结果


查找不存在的标签测试:

GameObject tagObj = GameObject.FindGameObjectWithTag("MainCamera1");
Debug.Log("根据标签查找游戏物体,是否查到:" + (tagObj != null));

不存标签

报错:UnityException: Tag: MainCamera1 is not defined. 翻译: MainCamera1是一个未定义的标签


FindGameObjectWithTag()得出结论:

  • 查找不到禁用物体,使用时需确认要查找的物体是启用(显示)状态;
  • 有多个有游戏物体使用同一标签时,尽量不使用FindGameObjectWithTag此方式查找单一游戏体,因为查找顺序会受到层级影响;
  • 查找未定义标签会报错,使用时需确认查找的字符串是已定义的标签;
  • 查找的标签是已定义但是未使用过,会找不到游戏物体,返回空值。

三,GameObject.FindObjectOfType()

和上面根据标签查找的逻辑差不多。

GameObject.FindObjectOfType<类型>(); :根据类型(组件/自定义脚本)查找并返回这个类。 GameObject.FindObjectsOfType<类型>() :根据类型(组件/自定义脚本)查找当前场景中所有这个类并返回一个这个类的数组。

void FindObjectOfType()
{
     Camera typeCamera = GameObject.FindObjectOfType<Camera>();
     Debug.Log("根据类型查找物体,是否查到:" + (typeCamera != null));
     
     Transform[] typeTransArr = GameObject.FindObjectsOfType<Transform>();
     for (int i = 0; i < typeTransArr.Length; i++)
     {
         Debug.Log("根据类型查找到的物体名称:" + typeTransArr[i].name);
     }
}

测试结果

FindObjectOfType()得出结论:

  • 查找不到禁用物体,使用时需确认要查找的物体是启用(显示)状态;
  • 查找场景中不存在类型时会返回null,不会报错;

通常使用情况为:初始化时在一个脚本中获取另一个脚本的引用,通过这种形式查找。【后多被单例取代】


好了本文就介绍这里了,感谢你观看至此。若对你有所帮助,希望可以三连支持下。若你还相关问题没有得到解决或者更好的处理方案,也希望你留言评论。

Unity基础 之 查找游戏物体的几种方式解析(二):juejin.cn/editor/draf…