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
|
26天前
|
图形学 开发者
【Unity小技巧】unity移动物体的探究——使用8个不同方法
【Unity小技巧】unity移动物体的探究——使用8个不同方法
17 1
|
26天前
|
图形学
【unity小技巧】实现投掷物品,比如长矛,刀具,手榴弹和其他物体
【unity小技巧】实现投掷物品,比如长矛,刀具,手榴弹和其他物体
13 1
|
26天前
|
图形学
【unity小技巧】Unity人物衣服布料系统的探究 —— Cloth组件
【unity小技巧】Unity人物衣服布料系统的探究 —— Cloth组件
10 0
|
26天前
|
图形学
【unity小技巧】创建FPS击中物体URP贴花
【unity小技巧】创建FPS击中物体URP贴花
10 0
|
26天前
|
人工智能 图形学
【unity小技巧】使用动画状态机脚本实现一个简单3d敌人AI功能
【unity小技巧】使用动画状态机脚本实现一个简单3d敌人AI功能
16 0
|
26天前
|
人工智能 定位技术 图形学
【Unity小技巧】一个脚本实现控制3D远程/近战敌人AI
【Unity小技巧】一个脚本实现控制3D远程/近战敌人AI
18 0
|
26天前
|
自然语言处理 图形学
【unity实战】一个通用的FPS枪支不同武器射击控制脚本
【unity实战】一个通用的FPS枪支不同武器射击控制脚本
16 0
|
26天前
|
开发工具 图形学
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
34 0
|
27天前
|
算法 图形学
【推荐100个unity插件之4】OpenFracture插件实现unity3d物体破裂和切割
【推荐100个unity插件之4】OpenFracture插件实现unity3d物体破裂和切割
12 0