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
{
......//略
}


相关文章
|
3月前
|
图形学
小功能⭐️Unity获取场景中所有物体
小功能⭐️Unity获取场景中所有物体
小功能⭐️Unity获取场景中所有物体
|
2月前
|
设计模式 存储 人工智能
深度解析Unity游戏开发:从零构建可扩展与可维护的游戏架构,让你的游戏项目在模块化设计、脚本对象运用及状态模式处理中焕发新生,实现高效迭代与团队协作的完美平衡之路
【9月更文挑战第1天】游戏开发中的架构设计是项目成功的关键。良好的架构能提升开发效率并确保项目的长期可维护性和可扩展性。在使用Unity引擎时,合理的架构尤为重要。本文探讨了如何在Unity中实现可扩展且易维护的游戏架构,包括模块化设计、使用脚本对象管理数据、应用设计模式(如状态模式)及采用MVC/MVVM架构模式。通过这些方法,可以显著提高开发效率和游戏质量。例如,模块化设计将游戏拆分为独立模块。
180 3
|
3月前
|
前端开发 图形学
Unity精华☀️UI和物体可见性的判断方法
Unity精华☀️UI和物体可见性的判断方法
|
3月前
|
图形学
小功能⭐️获取Unity游戏物体上,所挂载组件的名称
小功能⭐️获取Unity游戏物体上,所挂载组件的名称
|
3月前
|
图形学
小功能⭐️解决Unity无法对一个物体上的所有材质球进行更改
小功能⭐️解决Unity无法对一个物体上的所有材质球进行更改
|
3月前
|
图形学 C# 开发者
全面掌握Unity游戏开发核心技术:C#脚本编程从入门到精通——详解生命周期方法、事件处理与面向对象设计,助你打造高效稳定的互动娱乐体验
【8月更文挑战第31天】Unity 是一款强大的游戏开发平台,支持多种编程语言,其中 C# 最为常用。本文介绍 C# 在 Unity 中的应用,涵盖脚本生命周期、常用函数、事件处理及面向对象编程等核心概念。通过具体示例,展示如何编写有效的 C# 脚本,包括 Start、Update 和 LateUpdate 等生命周期方法,以及碰撞检测和类继承等高级技巧,帮助开发者掌握 Unity 脚本编程基础,提升游戏开发效率。
78 0
|
3月前
|
数据可视化 图形学
小功能⭐️Unity2018 Shader Graph——全息影像、物体消融
小功能⭐️Unity2018 Shader Graph——全息影像、物体消融
|
3月前
|
图形学
小功能⭐️Unity中利用材质自发光实现物体闪烁效果
小功能⭐️Unity中利用材质自发光实现物体闪烁效果
|
3月前
|
图形学
小功能⭐️Unity 如何判断物体是否在摄像机视野内或外
小功能⭐️Unity 如何判断物体是否在摄像机视野内或外
|
3月前
|
图形学
小功能⭐️Unity解决物体移动速度过快不能检测到碰撞
小功能⭐️Unity解决物体移动速度过快不能检测到碰撞