Unity 用脚本获取物体和组件(上)

简介: Unity 用脚本获取物体和组件(上)

一、物体、组件和对象

一个游戏物体是一个对象;没有被挂到物体上的脚本,是一个未被实例化的类,暂时还不是具体的对象;当脚本被挂到物体上后,就成了一个实实在在的对象。

脚本在执行时,一般已经挂到了某个对象上。因此在脚本代码中,可以随时访问脚本目前挂到了那个对象上,直接用gameObject就行

下面两个都可以,this可以被省略

Debug.Log(gameObject.name);

Debug.Log(this.gameObject.name);

二、获取组件的方法

获得某个物体后,就可以通过物体获取到它的每一个组件。举个例子,新建一个Test脚本文件并挂到球体上,脚本内容保持默认,为了得到Sphere Collider组件,可以直接用GetComponent()方法,将Test脚本内容修改如下。

using UnityEngine;
public class Test : MonoBehaviour
{
      SphereCollider collider;
      void Start()
       {
           collider=gameObject.GetComponent<SphereCollider>();
       }
}

上述是很常见的获取组件的代码,即先从当前脚本获取到游戏物体,再到游戏物体中找到某个组件。

Transform组件也可以用GetComponent()方法获得,但是由于Transform组件非常常用,因此随时刻通过字段transform访问,不需要通过代码获取

Unity为了方便,设计了获取组件的简便写法。思路是,在同一个物体上,从任意一个组件出发都可以直接获取到其他组件,不需要先获取游戏物体。也就是说,获取组件的写法有很多等价的形式,举例如下

collider=gameObject.getComponent<SphereCollider>();
//下面每一句写法均与上面一句等价
collider=this.GetComponent<SphereCollider>();
collider=GetComponent<SphereCollider>();
collider=transform.GetComponent<SphereCollider>();

如果需要获取多个相同组件,就要用到 GetComponents()方法,一般用一个数组存着。

三、获取物体的方法

1、通过名称获取物体

使用GameObject.Find()方法即可。举例:新建一个立方体,并挂一个TestGetObject脚本,内容如下

Public class TestGetGameObject : MonoBehaviour
{
     GameObject objMainCam;
     GameObject objMainLight;
     void Start()
     {
        objMainCam=GameObject.Find("Main Camera");
         objMainLight=GameObject.Find("Directional Light");
         Debug.Log(" 主摄像机:"+objMainCam.name);
         Debug.Log(" 主光源:"+objMainLight.name);
         //将主摄像机放在这个物体后方1m的位置
         objMainCam.transform.position=transform.position-transform.forward;
      }
}

GameObject.Find()方法比较常用,但它有两个弊端

  • 无法找到未激活的物体
  • 需要遍历场景中的所有物体,性能上来说非常低效    

为了验证第一个弊端,我们可以在上面的例子中,禁用场景光源(在Inspector窗口中取消勾选Drectional Light选项),这时再次运行,就会出现报错,异常类型为NullReferenceException(空引用)。双击该错误,就会定位到相应的源代码,源代码如下

Debug.Log(" 主光源:"+objMainLight.name);

这是由于其当前为空引用null,因此访问其name字段会报错。说明了GameObject.Find()方法的确无法找到未激活的物体

对于第二个弊端,在简单场景里很难察觉。而在一个完整的游戏中,场景中经常会有成千上万个物体,那时的效率差异就会想当明显。但这也不代表不能用GameObject.Find()方法。如果仅在Start方法中调用一次,然后将物体保存在objMainCam中,以后都不用重新查找,这样就不会产生明显的效率差异。

2、通过标签查找物体

通过例子来说明

//查找第一个标签为Player的物体

GameObject players=GameObject.FindGameObjectWithTag("Palyer");

//查找所有标签为Monster的物体,返回只是一个数组,结果可以是0个或多个

GameObject[] monsters=GameObject.FindGameObjectsWithTag("Monser");

除了Inspector中修改物体的标签,在脚本中也可以,举例如下

GameObject m=GameObject.FindGameObjectWithTag("Player");
m.tag="Cube";
if(m.CompareTag("Cube")) //CompareTag用法等效于m.tag=="Cube",推荐使用CompareTag
{
......//略
}


相关文章
|
2月前
|
存储 人工智能 Java
Unity优化——脚本优化策略4
Unity优化——脚本优化策略4
|
2月前
|
存储 人工智能 缓存
Unity优化——脚本优化策略3
Unity优化——脚本优化策略3
|
2月前
|
存储 缓存 Java
Unity优化——脚本优化策略2
Unity优化——脚本优化策略2
|
2月前
|
存储 XML 缓存
Unity优化——脚本优化策略1
Unity优化——脚本优化策略1
|
4月前
|
编解码 前端开发 人机交互
【Unity 3D】UI系统中UGUI各个组件的详细讲解(附源码 超详细)
【Unity 3D】UI系统中UGUI各个组件的详细讲解(附源码 超详细)
81 0
|
4月前
|
C# 图形学
【Unity 3D】游戏对象、添加删除获取组件、预制体Prefabs简介
【Unity 3D】游戏对象、添加删除获取组件、预制体Prefabs简介
75 0
|
4月前
|
API C# 图形学
【Unity 3D】常见API的讲解以及在C#脚本中的执行(附源码)
【Unity 3D】常见API的讲解以及在C#脚本中的执行(附源码)
64 1
|
4月前
|
人工智能 算法 BI
Unity——脚本与导航系统
Unity——脚本与导航系统
|
4月前
|
存储 XML JSON
Unity——脚本与序列化
Unity——脚本与序列化
|
4月前
|
编解码 前端开发 图形学
Unity 用脚本操作常用UI控件(上)
Unity 用脚本操作常用UI控件(上)