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


相关文章
|
10天前
|
图形学
Unity 射线移动物体Ray
在Unity中,通过射线检测实现3D物体的拖拽和移动。射线由起点和方向组成,使用`Physics.Raycast`检测与物体的交点。点击物体时,记录位置偏移量,拖动过程中更新物体位置。代码包括基本拖拽和上下拖动功能,适用于正交摄像机场景。测试时为物体设置特定标签(如&quot;JQR&quot;)以便区分和操作。 示例代码展示了如何通过鼠标事件控制物体移动,并结合层级掩码优化射线检测。具体实现包括:点击选中物体、拖动更新位置、释放鼠标取消选择。此外,提供了上下拖动的额外功能,通过按键切换模式。
|
10天前
|
图形学 开发者
unity 从工具栏拖动生成物体
在 Unity 中实现从工具栏拖动生成物体的功能,基于编辑器扩展、事件系统和预制体实例化。通过自定义编辑器窗口、处理鼠标事件(按下、移动、释放)及使用 Instantiate 方法,可实现拖动并生成预制体物体。代码示例展示了如何检测鼠标事件并在指定位置实例化物体。
|
10天前
|
存储 图形学 索引
unity 使物体跟随路径点自动移动位置
在Unity中,物体沿路径点自动移动的核心原理是通过预设路径点,控制物体依次移动。路径点可用空对象或三维向量数组定义,并按顺序存储。移动时,计算当前位置与下一个路径点的向量差以确定方向,使用`Vector3.MoveTowards`逐步靠近目标点。代码实现包括路径点设置、移动控制及插值计算,确保物体平滑移动和旋转。
|
10天前
|
图形学
unity 物体震动
在Unity中实现物体震动效果,主要通过改变物体的位置、旋转或缩放属性来模拟震动。以下是位置震动的实现原理及代码示例:通过随机生成微小偏移量并累加到物体位置上,在短时间内不断改变位置产生震动效果。生成随机偏移,并结合时间控制持续震动。
|
10天前
|
前端开发 图形学
unity UGUI跟随3D物体的坐标转换
在 Unity 中实现 UGUI 元素跟随 3D 物体,关键是将 3D 物体的世界坐标转换为屏幕或画布坐标。通过 Camera.WorldToScreenPoint 方法,可将 3D 物体位置映射到屏幕上,再更新 UGUI 元素的位置。代码示例展示了如何使用该方法,使 UGUI 图像跟随 3D 模型,并提供文字显示、图像和线条的显示/隐藏功能。
|
10天前
|
图形学
Unity 获取鼠标位置下的UGUI或3D物体
本文总结了两种检测方法,分别用于UGUI和3D物体的检测。第一种方法`GetOverUIobj`专门用于检测鼠标悬停的UGUI元素,通过`GraphicRaycaster`实现。第二种方法`GetOverWordGameObject`则同时适用于UI和3D物体检测,利用`PhysicsRaycaster`进行射线检测。两者均返回悬停对象或null。
|
11天前
|
图形学 开发者
Unity编辑器脚本(添加/删除)碰撞盒
这段代码提供了两个Unity编辑器工具,用于批量处理模型的碰撞盒。一是“一键添加所有碰撞盒”,通过选择模型的父物体,自动为其子物体添加`MeshCollider`。二是“一键清理所有Collider碰撞盒”,同样选择父物体后,递归删除子物体上的`BoxCollider`组件。两者均通过Unity的菜单项实现便捷操作,方便开发者快速调整场景中的物理属性。
|
5月前
|
设计模式 存储 人工智能
深度解析Unity游戏开发:从零构建可扩展与可维护的游戏架构,让你的游戏项目在模块化设计、脚本对象运用及状态模式处理中焕发新生,实现高效迭代与团队协作的完美平衡之路
【9月更文挑战第1天】游戏开发中的架构设计是项目成功的关键。良好的架构能提升开发效率并确保项目的长期可维护性和可扩展性。在使用Unity引擎时,合理的架构尤为重要。本文探讨了如何在Unity中实现可扩展且易维护的游戏架构,包括模块化设计、使用脚本对象管理数据、应用设计模式(如状态模式)及采用MVC/MVVM架构模式。通过这些方法,可以显著提高开发效率和游戏质量。例如,模块化设计将游戏拆分为独立模块。
304 3
|
6月前
|
图形学 C# 开发者
全面掌握Unity游戏开发核心技术:C#脚本编程从入门到精通——详解生命周期方法、事件处理与面向对象设计,助你打造高效稳定的互动娱乐体验
【8月更文挑战第31天】Unity 是一款强大的游戏开发平台,支持多种编程语言,其中 C# 最为常用。本文介绍 C# 在 Unity 中的应用,涵盖脚本生命周期、常用函数、事件处理及面向对象编程等核心概念。通过具体示例,展示如何编写有效的 C# 脚本,包括 Start、Update 和 LateUpdate 等生命周期方法,以及碰撞检测和类继承等高级技巧,帮助开发者掌握 Unity 脚本编程基础,提升游戏开发效率。
199 0
|
6月前
|
前端开发 图形学
Unity精华☀️UI和物体可见性的判断方法
Unity精华☀️UI和物体可见性的判断方法