坂田做网站建设好的网络公司/广州seo网站推广平台
【知识链】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 组件的引用。
以上方法中的参数includeInactive是个bool值,当为true时表示会获取非激活状态对象上的符合条件的组件,默认为false。
(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 的任何父级的引用。
(7)public bool TryGetComponent(out T component)
获取指定类型对象的组件。
这个方法和GetComponent的区别在于,当找不到指定类型的组件时,不会在编辑器中进行分配。来看下面这段代码:
if (objectToCheck.TryGetComponent<HingeJoint>(out HingeJoint hinge))
{hinge.useSpring = false;
}
在上面的代码中,如果找不到HingeJoint组件,不会产生异常,因为不会检查条件为false,不会执行“hinge.useSpring = false”这个语句。
在Unity 2022.3之后,还增加了下面三个方法,主要是用于访问Inspector里的组件。
(8)public Component GetComponentAtIndex(int index)
获取对指定 GameObject 上特定索引处的组件的引用。
(9)public int GetComponentCount():返回此 GameObject 上的组件数量。
(10)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 游戏开发过程中,使用脚本来添加、删除和修改组件是常见的需求,这种操作可以动态地改变游戏对象的行为和外观,适应各种游戏逻辑和需求。以下是一些具体的应用场景和实际案例:
-
动态添加组件
案例:角色拾取物品
在游戏中,角色可以拾取不同的装备(如武器、防具)。当角色拾取物品时,可能需要为角色动态添加新的组件以增加新功能。 -
动态删除组件
案例:移除临时效果
在一些游戏中,角色可能会受到临时效果(如加速、减速)。当这些效果过期时,需要移除相应的组件。 -
动态修改组件
案例:改变角色属性
在游戏中,角色可能会因为等级提升、技能效果等原因需要修改其属性。例如,角色升级后增加攻击力。 -
动态切换状态
案例:切换敌人AI状态
在复杂的AI系统中,敌人的行为可能需要根据玩家的动作进行切换。例如,敌人从巡逻状态切换到追击状态。 -
动态生成特效
案例:生成粒子特效
在游戏中,某些事件(如角色释放技能、敌人死亡)可能需要生成特效。可以通过脚本动态添加粒子系统组件。
第五章 总结
学习就是从薄到厚,再从厚到薄的过程。
今天学习的重点可以总结为两点:
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显示添加和删除的结果。
最终运行效果如下:
第七章 参考资料
- https://docs.unity3d.com/cn/current/Manual/GameObjects.html
- https://docs.unity3d.com/cn/current/Manual/UsingComponents.html
- https://docs.unity3d.com/2021.3/Documentation/ScriptReference/Component.html
【学以致用】参考答案:
任务1:
相关文章:

【Unity脚本】使用脚本操作游戏对象的组件
【知识链】Unity -> Unity脚本 -> 游戏对象 -> 组件 【知识链】Unity -> Unity界面 -> Inspector【摘要】本文介绍如何使用脚本添加、删除组件,以及如何访问组件 文章目录 引言第一章 游戏对象与组件1.1 什么是组件?1.2 场景、游戏对象与…...

学习VUE3——组件(一)
组件注册 分为全局注册和局部注册两种。 全局注册: 在main.js或main.ts中,使用 Vue 应用实例的 .component() 方法,让组件在当前 Vue 应用中全局可用。 import { createApp } from vue import MyComponent from ./App.vueconst app crea…...

2024-6-6 石群电路-25
2024-6-6,星期四,15:56,天气:晴,心情:晴。今天又是阳光明媚的一天打印了毕业论文,准备了一些毕业&答辩的材料,感觉离毕业越来越近了,加油学习喽~ 今日观看了石群老师…...

vue 文件预览mp4、txt、pptx、xls、xlsx、docx、pdf、html、xml
vue 文件预览 图片、mp4、txt、pptx、xls、xlsx、docx、pdf、html、xml 最近公司要做一个类似电脑文件夹的功能,支持文件夹操作,文件操作,这里就不说文件夹操作了,说说文件预览操作,本人是后端java开发,前端vue&#…...

生活中优秀学习习惯
早起: 23点睡--4至6点起床(睡足7、8个钟头),起来第一件事是工作(或学习)。不是吃早餐,不是刷牙。(空腹工作一段时间)--做推理让头脑运作,不要背书࿰…...

什么是负载均衡?在网络中如何实现?
负载均衡(Load Balancing)是一种网络技术,用于将网络请求或数据传输任务分发到多个服务器或处理单元上,以实现更高效的资源利用、更高的处理能力和更好的系统可靠性。负载均衡的目标是优化资源使用、最大化吞吐量、减少响应时间&a…...

【YOLOv10改进[Backbone]】图像修复网络AirNet助力YOLOv10目标检测效果 + 含全部代码和详细修改方式 + 手撕结构图 + 全网首发
本文带来的是图像复原网络AirNet,它由基于对比度的退化编码器( CBDE )和退化引导的恢复网络( DGRN )两个模块组成。可以在一个网络中恢复各种退化图像。AirNet不受损坏类型和级别的先验限制,仅使用观察到的损坏图像进行推理。本文中将使用图像修复网络AirNet助力YOLOv10的目标…...

ubuntu22.04 gitleb服务器满了,扩容机器的磁盘的详细步骤
在Ubuntu 22.04上为GitLab服务器扩容磁盘可以分为以下几步进行:增加磁盘空间、扩展文件系统,并确保数据安全。这些步骤可以应用于物理服务器或虚拟机(包括云服务中的实例)。以下是详细步骤: 1. 添加新的磁盘空间 1.1…...

kafka-集群-主题创建
文章目录 1、集群主题创建1.1、查看 efak1.2、创建 主题 my_topic1 并建立6个分区并给每个分区建立3个副本1.2.1、查看 my_topic1 的详细信息 1.3、停止 kafka-01实例,端口号为 9095 1、集群主题创建 1.1、查看 efak 已经有三个kafka实例 1.2、创建 主题 my_topic1…...

Python 连接 MySQL 及 SQL增删改查(主要使用sqlalchemy)
一、环境 工作中需要用到python和mysql数据库,本次文档记录相关操作。 环境:windows10、python 3.11.7 mysql版本:5.7 二、MySQL的连接和使用 本人使用过的两种方式 2.1方式一:sql为主 2.1.1创建连接 import sqlalchemy fro…...

JAVAEE值网络编程(2)_TCP流套接字及通信模型、TCP网络编程及代码实例
前言 在上一节内容中,我们介绍了什么是套接字,以及使用UDP数据报套接字网络编程, 最后我们还介绍了Java数据报套接字通信模型以及相关代码实例。在这一节我们将会介绍TCP流套接字编程。 一、流套接字及通信模型 1.1 TCP套接字 TCP࿰…...

【MMU】——MMU 页命中/缺页
文章目录 MMU 页命中/缺页MMU 命中MMU 缺页 MMU 页命中/缺页 MMU 命中 处理器产生一个虚拟地址。MMU生成 PTE 地址,并从高速缓存/主存请求得到它。高速缓存/主存向 MMU 返回 PTE。MMU 构造物理地址,并把它传送给高速缓存/主存。高速缓存/主存返回所请求…...

Win32和c++11多线程
Win32和c11多线程 一、概念1.线程的特点线程内核对象线程控制块线程是独立调度和分派的基本单位共享进程的资源 2.线程的上下文切换引起上下文切换的原因 3.线程的状态 二、Windows多线程API1.CreateThread创建线程2.获取线程ID3.关闭线程句柄4.挂起线程5.恢复线程6.休眠线程的…...

关于python包导入问题的重思考
将顶层目录直接设置为一个包 像这样,每一个文件从顶层包开始导入 这样可以解决我的问题,但是要注意的时,要避免使用出现上下级出现同名包的情况,比如: AutoServer--AutoServer--__init__.py--__init__.py这种情况下…...

攻防世界---misc---津门杯2021-m1
1、题目描述,下载附件是一张bmp格式的图片 2、直觉告诉我这和图片的颜色通道有关 3、于是我就尝试用stegslove打开图片 4、将颜色通道都改为0,点击preview 5、然后发现一串base64编码 6、解码得flag flag{l5DGqF1pPzOb2LU919LMaBYS5B1G01FD}...

【计算机视觉(8)】
基于Python的OpenCV基础入门——图像直方图 直方图图像直方图 图像直方图代码以及实现效果 直方图 直方图是一种用于描述图像亮度分布的统计工具。它将图像的像素亮度值按照不同的亮度等级进行计数,并以直方图的形式呈现出来。图像直方图可以显示图像中每个亮度级别…...

Linux操作系统:Redis在虚拟环境下的安装与部署
Redis下载方法 最近部署项目的时候用到了Redis,自己在安装的时候也碰到了一些列问题最终安装成功,记录一下自己的安装历程。前期准备: 服务器Linux版本:Centos8.4 64位(http://isoredirect.centos.org/centos/8/isos/…...

哈希表和二维矩阵的结合-2352. 相等行列对(新思路、新解法)
题目链接及描述 . - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/equal-row-and-column-pairs/description/?envTypest…...

深度学习中无监督学习
深度学习中的无监督学习 无监督学习(Unsupervised Learning)是一种机器学习方法,在没有标签数据的情况下,从数据中提取有意义的模式和特征。无监督学习广泛应用于深度学习中,以解决数据标注困难和大量无标签数据存在的…...

JVM基础知识
一、JVM的内存区域划分 一个进程在运行的时候,会向操作系统申请到内存资源,从来存放程序运行的相关数据。 JVM本质上就是一个java进程,在运行的时候也会从操作系统那搞一块内存,供Java代码执行使用。 JVM又把申请的一块内存根据不同的用途划分出了不同区域。 每一…...

618网购节,电商能挡住恶意网络爬虫的攻击吗?
目录 爬虫盗取电商数据的步骤 电商平台如何发现网络爬虫? 如何拦截违法网络爬虫 2023年,杭州中院审结了两起涉及“搬店软件”的不正当竞争案件。本案的原告是国内某大型知名电子商务平台的运营主体,而被告则是开发了一款名为“某搬家快速商品…...

Codeforces Round 951 (Div. 2) C、D(构造、线段树)
1979C - Earning on Bets 构造题:观察到k范围很小,首先考虑最终硬币总数可以是多少,我们可以先假设最终的硬币总数为所有k取值的最小公倍数,这样只需要满足每个结果添加1枚硬币即可赚到硬币。 // Problem: C. Earning on Bets //…...

elmentUI el-table 总结行
背景 原因:表格展示的都是明细数据,需要对当前的明细数据的部分字段进行汇总难点:汇总的条件不一定,有时候客户查的是1天,有时候是10天 官方写法 只开启开关 开启汇总开关如果没有汇总方法, 会自动汇总所有…...

【大数据】计算引擎:Spark核心概念
目录 前言 1.什么是Spark 2.核心概念 2.1.Spark如何拉高计算性能 2.2.RDD 2.3.Stage 3.运行流程 前言 本文是作者大数据系列中的一文,专栏地址: https://blog.csdn.net/joker_zjn/category_12631789.html?spm1001.2014.3001.5482 该系列会成体…...

Python | C# | MATLAB 库卡机器人微分运动学 | 欧拉-拉格朗日动力学 | 混合动力控制
🎯要点 🎯正向运动学几何矩阵,Python虚拟机器人模拟动画二连杆平面机械臂 | 🎯 逆向运动学几何矩阵,Python虚拟机器人模拟动画三连杆平面机械臂 | 🎯微分运动学数学形态,Python模拟近似结果 | …...

Signac|成年小鼠大脑 单细胞ATAC分析(1)
引言 在本教程中,我们将探讨由10x Genomics公司提供的成年小鼠大脑细胞的单细胞ATAC-seq数据集。本教程中使用的所有相关文件均可在10x Genomics官方网站上获取。 本教程复现了之前在人类外周血单核细胞(PBMC)的Signac入门教程中执行的命令。…...

【POSIX】运行时so库动态加载
运行时可以自己自定义so库的动态加载框架,主动去加载某些库,并调用其中的某些方法 首先写一些方法,并生成so库 // hello.cpp#include <iostream>/*使用 nm 命令查看 so 库的内容 */// 1. 使用extern // dlsym(handle, "hello&qu…...

爱普生SG2520CAA汽车电子中控专用晶振
随着汽车电子技术的飞速发展,汽车中控系统变得越来越智能化和复杂化。为了确保这些系统的高性能和高可靠性,选择符合AEC-Q200标准的高品质晶振至关重要。爱普生SG2520CAA晶振凭借其优异的特性,成为汽车电子中控系统的理想选择。 爱普生晶振SG…...

Vue——监听器简单使用与注意事项
文章目录 前言编写简单demo注意事项 前言 监听器,在官网中称为侦听器,个人还是喜欢称之为监听器。官方文档如下: vue 官网 侦听器 编写简单demo 侦听器在项目中通常用于监听某个属性变量值的变化,并根据该变化做出一些处理操作。…...

OpenCV的“画笔”功能
类似于画图软件的自由笔刷功能,当按住鼠标左键,在屏幕上画出连续的线条。 定义函数: import cv2 import numpy as np# 初始化参数 drawing False # 鼠标左键按下时为True ix, iy -1, -1 # 鼠标初始位置# 鼠标回调函数 def mouse_paint(…...