【Unity脚本】使用脚本操作游戏对象的组件

【知识链】Unity -> Unity脚本 -> 游戏对象 -> 组件
【知识链】Unity -> Unity界面 -> Inspector

摘要】本文介绍如何使用脚本添加、删除组件,以及如何访问组件

文章目录

  • 引言
  • 第一章 游戏对象与组件
    • 1.1什么是组件?
    • 1.2 场景、游戏对象与组件的关系
  • 第二章 在Inpector中操作组件
    • 2.1 添加组件
    • 2.2 删除组件
    • 2.3 修改组件
    • 2.4 变换组件
  • 第三章 使用脚本操作组件
    • 3.1 添加组件
    • 3.2 删除组件
    • 3.3 访问组件
  • 第四章 应用场景
  • 第五章 总结
  • 第六章 学以致用
  • 第七章 参考资料

引言

在现代游戏开发中,灵活操作游戏对象的组件已经成为提升游戏体验的重要手段。通过脚本动态添加、删除、修改组件以及切换状态和生成特效,开发者可以创建更加丰富和互动的游戏世界。这种方法不仅提高了游戏的可玩性和视觉效果,还使游戏的逻辑更加清晰和易于维护。在本文中,我们将深入探讨如何利用脚本来操作游戏对象的组件,并通过实际案例来展示其应用场景和实现方法。无论你是新手开发者还是有经验的游戏设计师,希望这篇文章能为你提供有价值的参考和启发。
在这里插入图片描述

第一章 游戏对象与组件

1.1什么是组件?

在Unity中,组件(Component)是构建游戏对象(GameObject)的基本单元。它们赋予游戏对象各种功能和行为。可以将组件看作是游戏对象的特性或能力,例如移动、渲染、物理交互等。

要在 Inspector 窗口中查看附加到 GameObject 的组件列表,请在 Hierarchy 窗口或 Scene 视图中选择一个 GameObject。
在这里插入图片描述

1.2 场景、游戏对象与组件的关系

Unity的核心设计架构可以概括为组件式架构,这种架构强调将功能拆分为独立的模块,这些模块可以自由组合和复用,以构建复杂的游戏对象和场景。

对于核心概念场景、游戏对象和组件三者之间的关系。
(1)场景是游戏的基本单位,它包含了游戏世界中的所有内容。每个场景可以看作是一个容器,包含有多个游戏对象和其相关的组件。
(2)游戏对象是Unity中所有实体的基础,它们是场景中存在的对象的抽象。游戏对象本身是一个空的容器,但通过添加不同的组件,游戏对象可以具有不同的功能和行为。
(3)组件是游戏对象的功能单元。每个组件负责实现特定的功能,例如渲染、物理、音频等。通过组合不同的组件,一个游戏对象可以实现复杂的行为。例如,一个游戏对象可以同时拥有渲染组件(用于显示)、物理组件(用于碰撞检测)和音频组件(用于播放声音)。

所以,三者之间是整体与部分的包含关系。场景由游戏对象组成,游戏对象由组件构成。
在这里插入图片描述

第二章 在Inpector中操作组件

2.1 添加组件

方法一:可以通过Component菜单向所选游戏对象添加组件。比如要添加Rigidbody组件,先在Hierarchy或Scene中选择一个游戏对象,然后从菜单中选择Component > Physics > Rigidbody。Inspector会显示Rigidbody的属性。
在这里插入图片描述
在这里插入图片描述
方法二:还可以在组件浏览器中添加组件。要打开组件浏览器,在检查器中选择“Add Component” 。
在这里插入图片描述
您可以在浏览器中按类别浏览组件,或者使用搜索框按名称查找组件。

您可以将任意数量或任意组合的组件附加到单个 GameObject。某些组件与其他组件结合使用效果最佳。例如,Rigidbody 与 Collider 配合使用。
有些组件之间是互斥的,比如Collider与Rigidbody 2D不能同时使用。

2.2 删除组件

右键单击组件的标题部分可以显示上下文菜单,也可从Inspector窗口组件面板右上角的菜单 (⋮) 中获得。
在这里插入图片描述
选择“Remove Component”,从 GameObject 中移除组件。注意:某些组件组合相互依赖(Hinge Joint仅在附加到Rigidbody时才有效);如果您尝试移除其他组件所依赖的组件,则会显示一条警告消息。

2.3 修改组件

当您将组件附加到 GameObject 时,组件的属性包含默认值。您可以在构建游戏时在编辑器中编辑这些值,也可以在运行游戏时在脚本中编辑这些值。

属性主要有两种类型:值和引用

您可以在Inspector中编辑值属性。值有多种类型,包括文本、切换按钮和下拉菜单。
对于引用属性,您可以将文件从 Project 视图拖到属性中,或者使用属性上的对象选择器(圆圈图标)。引用属性可以引用其他类型的组件、游戏对象或资产。

比如下图显示了Transform组件的Position属性是值类型,而Mesh Renderer组件中Material的值则是引用类型。
在这里插入图片描述

2.4 变换组件

Transform组件决定了 GameObject 的位置、旋转、缩放和父级状态。你可以将许多组件附加到 GameObject,但每个 GameObject 必须有且只有一个 Transform 组件你无法移除 Transform 或创建没有 Transform 组件的 GameObject
在这里插入图片描述
要创建空 GameObject,请选择GameObject > Create Empty。当您选择新的 GameObject 时,Inspector 会显示具有默认值的 Transform 组件。
更多参考:https://docs.unity3d.com/cn/current/Manual/class-Transform.html

第三章 使用脚本操作组件

3.1 添加组件

添加组件的方法是:public T AddComponent()。比如:

 SphereCollider sc = gameObject.AddComponent<SphereCollider>() as SphereCollider;

示例:添加Rigidbody组件
1.在Project中Asset文件夹,创建一个脚本AddComponentDemo.cs,内容如下。
2.菜单GameObject -> 3D Object -> Cube,创建一个Cube,将脚本AddComponentDemo.cs拖入到这个Cube上。

3.点击Play运行,在Game窗口中,按键盘上的A。在Hierarchy中选中Cube,可以看到Rigidbody组件已经添加成功。Game窗口中,Cube因为有了Rigidbody开始下落。

1.using UnityEngine;
2.
3.public class AddComponentDemo : MonoBehaviour
4.{
5.    Rigidbody rb = null;
6.
7.    void Update()
8.    {
9.        if (Input.GetKeyDown(KeyCode.A))
10.        {
11.            AddComponentTest();
12.        }
13.    }
14.
15.    void AddComponentTest()
16.    {
17.        rb = gameObject.AddComponent<Rigidbody>();
18.
19.        if(rb != null )
20.        {
21.            Debug.Log("已添加Rigidbody组件");
22.        }
23.    }
}

3.2 删除组件

(1)Destroy方法
此方法可以删除游戏对象、组件或资产。例如:

public static void Destroy(Object obj, float t = 0.0F);

对象obj在当前更新循环结束后立即销毁,t如果指定了时间,则在几秒后销毁。如果obj是组件,则此方法从GameObject中移除组件并销毁它。如果obj是GameObject,则它会销毁GameObject 、其所有组件以及GameObject的所有变换子项。实际对象销毁总是延迟到当前更新循环之后,但总是在渲染之前完成。

注意:销毁 MonoBehaviour 脚本时,在移除脚本之前会调用OnDisable和OnDestroy。

示例:在上面添加组件的基础上,我们增加一个功能:按D键删除Rigidbody组件,完整代码如下。

1.using UnityEngine;
2.
3.public class AddComponentDemo : MonoBehaviour
4.{
5.    Rigidbody rb = null;
6.
7.    void Update()
8.    {
9.        if (Input.GetKeyDown(KeyCode.A))
10.        {
11.            AddComponentTest();
12.        }
13.
14.        if(Input.GetKeyDown(KeyCode.D))
15.        {
16.            RemoveComponentTest();
17.        }
18.    }
19.
20.    void AddComponentTest()
21.    {
22.        rb = gameObject.AddComponent<Rigidbody>();
23.
24.        if(rb != null )
25.        {
26.            Debug.Log("已添加Rigidbody组件");
27.        }
28.    }
29.
30.    void RemoveComponentTest()
31.    {
32.        Destroy(rb);
33.         Debug.Log("已移除Rigidbody组件");
34.    }
35.}

(2)DestroyImmidiate方法

public static void DestroyImmediate(Object obj, bool allowDestroyingAssets = false);

立即销毁该对象obj。不过强烈建议使用 Destroy方法。
此函数应仅在编写编辑器代码时使用,因为延迟销毁永远不会在编辑模式下调用。在游戏代码中,应改用Object.Destroy。销毁始终会延迟(但在同一帧内执行)。请谨慎使用此函数,因为它可能会永久销毁资产!另请注意,永远不应迭代数组并销毁正在迭代的元素。这将导致严重问题(作为一般编程实践,而不仅仅是在 Unity 中)。

3.3 访问组件

我们先来看一下访问组件的方法有哪些:
(1)public T GetComponent()
获取对指定 GameObject上T类型组件的引用。
(2)public T GetComponentInChildren(bool includeInactive = false)
获取对指定 GameObject 或 GameObject 的任何子项上类型 T 组件的引用。
(3)public T GetComponentInParent(bool includeInactive = false)
获取对指定 GameObject 或 GameObject 的任何父级上类型 T 组件的引用。
(4)public T[] GetComponents()
获取对指定 GameObject 上所有类型 T 组件的引用。
(5)public T[] GetComponentsInChildren(bool includeInactive)
获取对指定 GameObject 上所有类型 T 的组件以及该 GameObject 的任何子组件的引用。
(6)public T[] GetComponentsInParent(bool includeInactive)
获取对指定 GameObject 上所有类型 T 的组件以及该 GameObject 的任何父级的引用。

以上方法中的参数includeInactive是个bool值,当为true时表示会获取非激活状态对象上的符合条件的组件,默认为false。

在Unity 2022.3之后,还增加了下面三个方法,主要是用于访问Inspector里的组件
(7)public Component GetComponentAtIndex(int index)
获取对指定 GameObject 上特定索引处的组件的引用。
(8)public int GetComponentCount():返回此 GameObject 上的组件数量。
(9)public int GetComponentIndex(Component component)
获取指定 GameObject 上指定组件的索引。

接下来就以GetComponen()为例详细说明一下使用方法。

  • 返回值:T,如果找到 该类型的组件,则为其引用,否则为null。
  • 方法描述:T获取对指定 GameObject类型组件的引用。

此方法的典型用法是在对脚本所在 GameObject 以外的其他 GameObject 的引用上调用它。例如:

myResults = otherGameObject.GetComponent<ComponentType>()

但是,如果在 MonoBehaviour 类中编写代码,则可以省略前面的 GameObject 引用,以便从脚本所附加到的同一GameObject中获取组件。在这种情况下,实际上是在调用Component.GetComponent,因为脚本本身是一种组件,但结果与引用GameObject本身一样。例如:

myResults = GetComponent<ComponentType>()

GetComponent仅返回在调用它的GameObject上找到的第一个匹配组件,并且检查组件的顺序未定义。因此,如果有多个指定类型可以匹配,并且需要找到一个特定的类型,则应使用Component.GetComponents并检查返回的组件列表以识别所需的组件。

通过这些方法获取到组件后,就可以对组件的属性进行修改。
比如我们获取到Rigidbody组件后,改变其mass属性的值。

Rigidbody rb = GetComponent<Rigidbody>();
rb.mass = 0.5f;

第四章 应用场景

在 Unity 游戏开发过程中,使用脚本来添加、删除和修改组件是常见的需求,这种操作可以动态地改变游戏对象的行为和外观,适应各种游戏逻辑和需求。以下是一些具体的应用场景和实际案例:

  1. 动态添加组件
    案例:角色拾取物品
    在游戏中,角色可以拾取不同的装备(如武器、防具)。当角色拾取物品时,可能需要为角色动态添加新的组件以增加新功能。

  2. 动态删除组件
    案例:移除临时效果
    在一些游戏中,角色可能会受到临时效果(如加速、减速)。当这些效果过期时,需要移除相应的组件。

  3. 动态修改组件
    案例:改变角色属性
    在游戏中,角色可能会因为等级提升、技能效果等原因需要修改其属性。例如,角色升级后增加攻击力。

  4. 动态切换状态
    案例:切换敌人AI状态
    在复杂的AI系统中,敌人的行为可能需要根据玩家的动作进行切换。例如,敌人从巡逻状态切换到追击状态。

  5. 动态生成特效
    案例:生成粒子特效
    在游戏中,某些事件(如角色释放技能、敌人死亡)可能需要生成特效。可以通过脚本动态添加粒子系统组件。

第五章 总结

学习就是从薄到厚,再从厚到薄的过程。

今天学习的重点可以总结为两点:
1.场景、游戏对象和组件之间是包含关系
2.掌握对组件的操作方法
(1)添加组件:AddComponent()
(2)删除组件:Destroy(component)
(3)编辑组件:GetComponent()

第六章 学以致用

下面就通过任务来刻意训练一下刚学到的知识吧。
在场景中创建一个平面(Plane)和一个球体(Sphere),将球体的位置设置为 (0,1,0),并删除场景中的Directional Light。当你完成任务后就可以将脚本挂载到球体进行测试。

任务1:手动添加和删除组件
运行的效果:
(1)按A时添加Light组件。
(2)按G时将Light组件的color设置为红色,range设置3,intensity设置为10。
(3)按D时删除Light组件。
(4)通过Log显示添加和删除的结果。

最终运行效果如下:
在这里插入图片描述

第七章 参考资料

  1. https://docs.unity3d.com/cn/current/Manual/GameObjects.html
  2. https://docs.unity3d.com/cn/current/Manual/UsingComponents.html
  3. https://docs.unity3d.com/2021.3/Documentation/ScriptReference/Component.html

【学以致用】参考答案:
任务1:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/20039.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php使用openssl返回false报错0308010C

本地php使用openssl返回false, 但是在服务器上测试正常openssl_encrypt($jsonStr, DES-ECB, $key, OPENSSL_RAW_DATA, ); 查看错误 openssl_error_string(); error:0308010C:digital envelope routines::unsupported 原因是: 服务器上的openssl是1.1版本, 本地是3.0版本 通…

C++回调函数

#include <iostream> #include <functional> // 为了使用 std::function // 声明一个回调函数类型 typedef std::function<void()> Callback11;// 调用函数&#xff0c;它接受一个回调函数作为参数 void process(Callback11 callback123) {// 在这里执…

直播领域新宠—第三代大模型无人直播系统:提升销售业绩的秘密武器

随着科技的飞速发展和人们对智能化生活的追求&#xff0c;直播领域也迎来了革新性的突破。第三代大模型无人直播系统&#xff0c;作为直播领域的新宠&#xff0c;正以其独特的魅力和优势&#xff0c;成为提升销售业绩的秘密武器。 首先&#xff0c;第三代大模型无人直播系统具…

2024山软创新实训:软件系统架构

软件架构 本文着重介绍本应用&#xff1a;基于开源LLM的易学大模型软件系统的架构。在经过2个月的探索、选型、实验、开发后&#xff0c;我们团队终于把整个系统的各块拼图搭建了起来&#xff0c;现在剩下的是集成、评测、优化和部署的工作。 1. Distributed System 整个项目…

【Android】

hint在text显示提示内容 设置主键&#xff0c;在mainactivity // 获取SharedPreferences对象存放的用户名和密码&#xff0c;并设为相应组件的值 //指定key的值&#xff0c;及获取不到值时使用的默认值 String sName sp.getString("name", "unknown")…

媲美苹果、三星uwb芯片,飞睿智能UWB SIP芯片方案,创新无线传输、测距、精准定位新纪元

超宽带&#xff08;UWB&#xff09;技术作为一种新兴的无线通信技术&#xff0c;以其高精度定位、低功耗、高安全性和强抗干扰能力等优势&#xff0c;在全球范围内得到了广泛关注和快速应用。 2019 年&#xff0c;苹果iPhone11搭载UWB芯片&#xff0c;火极一时的AirDrop隔空投…

MODIS L1B数据规格介绍

1.MODIS 仪器概述 MODIS是EOS AM-1系列卫星的主要探测仪器&#xff0c;也是EOS Terra平台上唯一进行直接广播的对地观测仪器。MODIS是当前世界上新一代“图谱合一”的光学遥感仪器&#xff0c;具有36个光谱通道&#xff0c;分布在0.4-14um的电磁波谱范围内&#xff0c;波段范围…

Docker Hub 国内镜像源配置

Docker Hub 国内镜像源配置 Docker Hub 国内镜像源是指在国内境内提供 Docker 镜像服务的镜像源。由于国际网络带宽等问题&#xff0c;国内用户下载 Docker 镜像通常速度较慢。因此&#xff0c;为了解决这个问题&#xff0c;一些国内的公司和组织提供了 Docker 镜像的国内镜像…

MySQL--MHA高可用及读写分离

一、什么是高可用 1.企业级高可用标准&#xff1a;全年无故障时间 全年无故障时间全年故障时间具体时间99.9%0.1%525.6 minkeeplive双主 &#xff08;切换需要人为干预&#xff09;99.99%0.01%52.56 minMHA &#xff08;半自动化&#xff09;99.999%0.001%5.256 minPXC、MGR、…

解决3D模型变黑及贴图不显示的问题---模大狮模型网

在3D建模和渲染过程中&#xff0c;模型变黑或贴图不显示是常见的挑战之一。这不仅影响了模型的视觉效果&#xff0c;还可能导致后续的工作流程受阻。本文将针对这两个问题&#xff0c;提供详细的解决方法和步骤&#xff0c;帮助读者快速有效地解决问题。 一、检查并调整光照设置…

Day 8:1461. 检查一个字符串是否包含所有长度为 K 的二进制子串

Leetcode 1461. 检查一个字符串是否包含所有长度为 K 的二进制子串 给你一个二进制字符串 s 和一个整数 k 。如果所有长度为 k 的二进制字符串都是 s 的子串&#xff0c;请返回 true &#xff0c;否则请返回 false 。 截取每个长度为 k 的字符串&#xff0c;加入 Set 中&#x…

根据状态转移图实现时序电路 (三段式状态机)

看图编程 * ** 代码 module seq_circuit(input C ,input clk ,input rst_n,output wire Y ); reg [1:0] current_stage ; reg [1:0] next_stage ; reg Y_reg; //输出//第一段 &#xff1a; 初始化当前状态和…

汇总区间,合并区间

题目一&#xff1a; 代码如下&#xff1a; vector<string> summaryRanges(vector<int>& nums) {vector<string> ret;if (nums.size() 0)return ret;int n nums.size();int i 0;while (i < n){int prev i;i;while (i < n && nums[i] n…

烧脑的逻辑图又来了,精力绝对不是花费在做图上。

逻辑图设计之所以比较耗费精力&#xff0c;主要是因为它需要进行深入的思考和分析&#xff0c;以确保设计的逻辑正确、完整和可行。以下是一些可能导致逻辑图设计耗费精力的原因&#xff1a; 复杂性&#xff1a;逻辑图设计通常涉及到复杂的业务流程和系统架构。设计师需要理解各…

Spring boot 集成thymeleaf

Spring boot 集成thymeleaf 背景 自己通过Spring boot集成通义千问实现了一个智能问答系统。Spring boot集成通义千问已经完成&#xff0c;现在需要做一个简单的页面展示&#xff0c;作为一个八年没有摸过前端的后端开发人员&#xff0c;不得不又拿起了html和thymeleaf。 Sp…

用例与系统顺序图

习题 问题 考察点 1.Use Cases 用例绘制 列出8个Use Cases, 按优先权分成三个档次, 并分别用Fully dressed、Causual和Brief方式描述 建议:用Fully dressed方式描述的Use Cases应该是项目比较核心,而且需要尽快研制的功能模块;该功能模块的内容比较充实;不要采用如登陆验…

摘下戛纳大奖的《狗阵》,救得了华谊吗?

随着第77届戛纳国际电影节成功落幕&#xff0c;《狗阵》无疑成为了华语电影的最大赢家。 今年的戛纳电影节可以说是华语电影大年&#xff0c;《风流一代》《狗阵》《酱园弄》《九龙城寨之围城》等多部重量级影片亮相戛纳。 但最终抱得奖项而归的只有管虎导演的《狗阵》&#…

appium元素定位工具_uiautomatorviewer.bat

特点&#xff1a; uiautomatorviewer是android-sdk自带的元素定位工具uiautomatorviewer只能用于安卓系统&#xff1b;它是通过截屏分析XML布局文件方式&#xff0c;来提供控件信息的查看服务 uiautomatorviewer.bat 基本使用 路径&#xff1a;这个工具是Android SDK中自带&…

统计计算六|自助法及置换检验(Bootstrap and Permutation Test)

系列文章目录 统计计算一|非线性方程的求解 统计计算二|EM算法&#xff08;Expectation-Maximization Algorithm&#xff0c;期望最大化算法&#xff09; 统计计算三|Cases for EM 统计计算四|蒙特卡罗方法&#xff08;Monte Carlo Method&#xff09; 统计计算五|MCMC&#x…

flutter开发实战-下拉刷新继续下拉路由进入活动页面实现

flutter开发实战-下拉刷新继续下拉路由进入活动页面实现 很多应用都有首页通过下拉刷新&#xff0c;继续下拉进入新的活动会场进入方式。在Flutter中&#xff0c;也可以通过pull_to_refresh来实现控制刷新页&#xff0c;继续下拉进入新的活动会场页面 一、引入pull_to_refres…