【Unity脚本】Unity中如何按类型查找游戏对象(GameObject)

【知识链】Unity -> 脚本系统 -> 访问游戏对象 -> 按类型访问游戏对象

摘要:本文介绍了Unity中按类型查找游戏对象(GameObject)的五种方法,并提出了使用这些方法的最佳实践。

本文目录

    • 一、访问游戏对象的方法
    • 二、如何按类型查找游戏对象
    • 三、五种查找方法的使用
    • 四、最佳实践
    • 五、学以致用 - 随堂测验
    • 六、福利:给你介绍个对象:)

一、访问游戏对象的方法

在Unity中,对游戏对象进行操作前,首要步骤是确保能准确查找到目标游戏对象。Unity提供了多种脚本访问游戏对象的方法,以满足不同需求:

(1)通过名称访问:使用Find(string name)方法,通过指定游戏对象的名称来查找并获取该对象。

(2)通过标签访问:FindGameObjectsWithTag(string tag)FindWithTag(string tag)方法允许开发者通过标签来查找具有相同标签的游戏对象集合或单个对象。

(3)通过类型访问:FindObjectByType(Type type)方法允许开发者按照游戏对象的类型进行查找。值得注意的是,按名称和按标签的访问方法属于GameObject类,而按类型访问的方法则属于更广泛的Object类。由于GameObjectObject的子类,因此也可以通过类型访问游戏对象。

请添加图片描述
在这里插入图片描述

二、如何按类型查找游戏对象

按类型查找游戏对象作为Object类的一个重要方法,其核心功能在于实现针对特定类型的游戏对象的检索。该方法主要提供了五个不同的重载方法,以便用户能够根据不同的需求进行精确查找。具体方法如以下表格所示:

方法说明重载
FindAnyObjectByType查找任意按指定类型匹配的已加载的游戏对象(未排序时返回第一个匹配)public static Object FindAnyObjectByType(Type type, FindObjectsInactive findObjectsInactive);
FindFirstObjectByType查找第一个按类型匹配的已加载的游戏对象(排序后返回第一个匹配对象)public static Object FindFirstObjectByType(Type type, FindObjectsInactive findObjectsInactive);
FindObjectsByType查找所有按类型匹配的已加载的游戏对象(可以选择是否按InstanceID排序)public static Object[] FindObjectsByType(Type type, FindObjectsInactive findObjectsInactive, FindObjectsSortMode sortMode);
FindObjectOfType查找第一个按类型匹配的已加载的游戏对象(默认按InstanceID排序)public static Object FindObjectOfType(Type type, bool includeInactive);
FindObjectsOfType查找所有按类型匹配的已加载的游戏对象(默认按InstanceID排序)public static Object[] FindObjectsOfType(Type type, bool includeInactive);

在正式介绍各个方法的使用细节之前,我们首先需要明确每个方法中涉及的Type参数的含义。在此处,Type特指Object的类型定义。请注意,在后续的最佳实践部分,我们会明确指出,上述方法并不适用于查找资产类(Assets)资源。此外,本文末尾还将对Object的类别进行详细阐述,以便读者更好地理解与应用。

三、五种查找方法的使用

这五种方法均具备四种重载形式,现以FindAnyObjectByType方法为例进行详尽阐述,其余四种方法的使用方式与之相类似。

1. FindAnyObjectByType
重载方法:

public static T FindAnyObjectByType();
public static T FindAnyObjectByType(FindObjectsInactive findObjectsInactive);
public static Object FindAnyObjectByType(Type type);
public static Object FindAnyObjectByType(Type type, FindObjectsInactive findObjectsInactive);

(1)四种重载,可以分为两类,一是泛型方法,另外一种是指定对象类型的方法。
(2)从参数上看,两个参数
Type:要查找的对象的类型
FindObjectsInactive:是否包含附加到非活动游戏对象的组件。如果不指定此参数,则此函数不会在结果中包含非活动对象。

那如何选择在什么场合使用哪种重载方法呢?

如果你在编译时就知道要查找的类型,并且希望代码简洁,可以使用泛型方法 FindAnyObjectByType。
如果类型是在运行时动态确定的,或者你需要在不确定类型的情况下查找对象,可以使用 FindAnyObjectByType(Type, FindObjectsInactive)。

示例代码1 - 使用泛型方法

using UnityEngine;public class FindAnyObjectByTypeWithInactiveExample : MonoBehaviour {void Start() {// 查找第一个匹配类型为 PlayerController 的对象,包括非活动对象PlayerController playerController = Object.FindAnyObjectByType<PlayerController>(FindObjectsInactive.Include);if (playerController != null) {Debug.Log("Found a PlayerController object.");} else {Debug.Log("No PlayerController object found.");}}
}

示例代码2 - 使用常规方法

using UnityEngine;public class FindAnyObjectByTypeWithInactiveExample : MonoBehaviour {void Start() {// 查找第一个匹配类型为 PlayerController 的对象,包括非活动对象PlayerController playerController = (PlayerController)Object.FindAnyObjectByType(typeof(PlayerController), FindObjectsInactive.Include);if (playerController != null) {Debug.Log("Found a PlayerController object.");} else {Debug.Log("No PlayerController object found.");}}
}

2. FindFirstObjectByType

此方法用于查找第一个匹配类型的对象,包括非活动对象。

public static Object FindFirstObjectByType(Type type, FindObjectsInactive findObjectsInactive);

findObjectsInactive: 是否包含附加到非活动游戏对象的组件。如果不指定此参数,则此函数不会在结果中包含非活动对象。

2. FindObjectsByType

此方法用于查找所有匹配类型的对象,可以选择是否包含非活动对象,并对结果进行排序。

public static T[] FindObjectsByType(FindObjectsInactive findObjectsInactive, FindObjectsSortMode sortMode);

sortMode: 是否以及如何对返回的数组进行排序。不对数组进行排序可使此函数的运行速度显著加快。

FindObjectsSortMode有两个值

(1)InstanceID:对结果按InstanceID升序排列(InstanceID是Unity内部对每个对象指定的一个整数ID,只存在于Unity运行时,不能用于游戏逻辑)

(2)None:不对结果进行排序

4. FindObjectOfType

此方法用于查找一个类型的对象,默认查找活动对象,但可以选择包含非活动对象。

public static Object FindObjectOfType(Type type, bool includeInactive);

includeInactive:是否包含非活动游戏对象。如果不指定此参数,则此函数不会在结果中包含非活动对象。

5. FindObjectOfType

此方法用于查找所有匹配类型的对象,可以选择是否包含非活动对象。

public static Object[] FindObjectsOfType(Type type, bool includeInactive);

经过对比分析,FindObjectByType与FindObjectOfType的主要差异在于前者提供了是否进行排序的选项,而后者则默认对查找结果进行了排序处理。

值得注意的是,自2023.1版本起,FindObjectOfType和FindObjectsOfType这两个方法已被弃用。因此,在学习和使用过程中,我们应主要关注前三个方法。

弃用这两个方法的原因在于,它们对查找结果进行排序的过程消耗了大量时间,占据了整个查找过程用时的90%以上。为了提高效率,开发团队决定废除这两个方法,并推荐使用FindObjectByType等三个方法,由开发者自行根据需求决定是否对查找结果进行排序。如需更多信息,请查阅相关文档。
在这里插入图片描述

翻译一下就是:

使用Volvo测试项目和 Gigaya 对进入/退出游戏模式进行分析表明,在 FindObjectsOfType() 中花费的时间中约有 95% 用于按 InstanceID 对数组进行排序,尽管在几乎所有情况下这都被认为是不必要的。

在 Volvo 项目 (2022.1) 中,在单次进入/退出播放模式循环中,Object::FindObjectsOfType() 花费了 203 毫秒,其中 190 毫秒用于排序 (93.6%)

在 Gigaya (2021.3) 中,在单次进入/退出播放模式循环中,Object::FindObjectsOfType() 花费了 496 毫秒,其中 461 毫秒用于排序 (92.9%)

在 #devs-scripting 中,关于此问题的可能解决方案进行了长时间的讨论 (https://unity.slack.com/archives/C06TPSM32/p1651840563109579),现在达成的共识是弃用 FindObjectsOfType() 并将其替换为 FindObjectsByType()

让用户选择是否执行排序

请注意,让 API 更新程序自动将 FindObjectsOfType() 转换为FindObjectsByType(FindObjectsSortMode.InstanceID),因为我们确实希望用户根据具体情况评估其使用情况,并且只在必要时选择

排序以最大化性能增益

* 计划是:

2023.1 :

* FindObjectsOfType() 已过时(警告),将用户引导至 FindObjectsByType

* FindObjectOfType() 已过时(警告),将用户引导至 FindFirstObjectByType 和 FindAnyObjectByType

2023.2

* FindObjectsOfType() 已过时(错误),将用户引导至 FindObjectsByType

* FindObjectOfType() 已过时(错误),将用户引导至 FindFirstObjectByType 和 FindAnyObjectByType

2024.2

* FindObjectsOfType() 已删除

* FindObjectOfType() 已删除

这项工作已在 https://jira.unity3d.com/browse/COPT-854 中记录

在这里插入图片描述

四、最佳实践

当然在使用上述方法过程中还有以下需要注意的。

(1)以上方法都不能查看资源(例如mesh, texture, prefab),或者未激活游戏对象。如果对象设置了HideFlags.Dontsave标签,这个对象也不会被返回。可以使用 Resources.FindObjectsOfTypeAll 来避免以上的限制。

(2)在编辑器中,默认情况下会搜索场景视图。如果要在预制件阶段查找对象,请参阅StageUtility API。

(3)这里面速度最快的是FindAnyObjectByType,因为不会对结果进行排序。

五、学以致用 - 随堂测验

测验1:寻找任意一个指定类型的游戏对象
场景描述
你正在开发一个Unity项目,需要在游戏启动时找到场景中的任意一个Light组件,并根据它的属性设置其他组件的初始状态。
问题:在这种情况下,你应该使用哪种方法来查找Light组件?
A. FindAnyObjectByType()
B. FindFirstObjectByType()
C. FindObjectsByType()

测验2:寻找场景中所有的敌人对象
场景描述
你正在开发一个塔防游戏,需要在每一帧更新时遍历所有的敌人对象,以便调整它们的行为和状态。敌人对象都包含一个Enemy脚本组件。
问题:在这种情况下,你应该使用哪种方法来查找所有Enemy组件?
A. FindAnyObjectByType()
B. FindFirstObjectByType()
C. FindObjectsByType()

测验3:寻找第一个活动的玩家对象
场景描述
你正在开发一个多人游戏,需要在玩家加入游戏时找到第一个活动的PlayerController组件,以便初始化该玩家的相关数据。
问题:在这种情况下,你应该使用哪种方法来查找第一个活动的PlayerController组件?
A. FindAnyObjectByType()
B. FindFirstObjectByType()
C. FindObjectsByType()

六、福利:给你介绍个对象:)

(一)关于类型的说明
本文中所有方法参数中的Type指的是游戏对象的类型。在Unity中,Object类是所有游戏对象及组件的基类。从Object派生出来的所有类如下图所示。我们可以看出,绝大多数的类都属于Component(组件),这也和Unity组件化的架构设计是呼应的。
在这里插入图片描述
(二)介绍一下游戏对象

本文中提到按类型查找游戏对象的方法是不能用来查找游戏资产的。下面来介绍一下Unity中游戏对象(Object)和游戏资产(Assets)的区别与联系。

简单来说,游戏对象是游戏世界中的实体,动态存在并且可以在运行时操作,而游戏资产是静态资源,定义了游戏对象的属性和行为。游戏对象可以在Inspector中编辑属性,而游戏资产则是通过Project进行管理。

对于游戏对象和资产的关系,我们可以以搭建舞台为例:

  • 舞台上的道具、灯光、布景、音响等都是资产:这些道具、灯光、布景、音响等存储在仓库里,定义了舞台上将要使用的所有资源。
  • 当这些元素被使用在舞台上时,它们就成了游戏对象:这些元素一旦被放置在舞台上,并开始演出,它们就变成了具体的对象,成为演出的一部分。

二者间联系

  • 实例化:就像从仓库中拿出道具、灯光等并布置到舞台上,游戏资产也可以被实例化为游戏对象,并放置在游戏场景中。
  • 引用:道具的具体外观、灯光的颜色和强度等属性都由这些资产决定,正如游戏对象引用游戏资产来定义其属性和行为。

【学以致用】随堂测验的正确答案:(1)A(2)C(3)B

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

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

相关文章

【个人博客搭建】(20)获取操作用户信息(IHttpContextAccessor)

IHttpContextAccessor在ASP.NET Core中扮演着至关重要的角色。它为开发者提供了一种方便的方式来访问和操作HttpContext对象&#xff0c;从而允许在整个应用程序中轻松地管理和使用HTTP请求和响应的相关信息。下面将深入探讨IHttpContextAccessor的作用、使用方法以及如何通过它…

[ue5]建模场景学习笔记(1)——混合材质

卷首&#xff1a;这部分会记录建模场景等相关学习内容&#xff0c;与ue引擎学习笔记不同的是&#xff0c;可能会略过一些基础内容&#xff0c;因为部分知识在blender中已经学习过了&#xff0c;不再继续记录。 1.需求分析&#xff1a; 想构建一个山地的场景&#xff0c;在ue5中…

解读vue3源码-1

提示&#xff1a;看到我 请让滚去学习 vue3渲染流程 文章目录 vue3渲染流程vue3的3个核心&#xff1a;1.响应式模块(Reactivity Module)--创建响应式数据2.编译模块(Compiler Module)--模版编译器将html转换为一个渲染函数3.渲染模块(Renderer Module) 渲染流程&#xff1a;1.首…

python办公自动化——(二)替换PPT文档中图形数据-柱图

效果: 数据替换前 &#xff1a; 替换数据后&#xff1a; 实现代码 import collections.abc from pptx import Presentation from pptx.util import Cm,Pt import pyodbc import pandas as pd from pptx.chart.data impo…

广东海上丝绸之路文化促进会正式批复荐世界酒中国菜的指导单位

广东海上丝绸之路文化促进会正式批复成为“世界酒中国菜”系列活动指导单位 近日&#xff0c;广东海上丝绸之路文化促进会近日正式批复荐酒师国际认证&#xff08;广州&#xff09;有限公司&#xff0c;成为备受瞩目的“世界酒中国菜”系列活动的指导单位。此举旨在通过双方的…

IDEA中各种Maven相关问题(文件飘红、下载依赖和启动报错)

错误情况 包名、类名显示红色、红色波浪线&#xff0c;大量依赖提示不存在&#xff08;程序包xxx不存在&#xff09; 工程无法启动 一、前提条件 1、使用英文原版IDEA 汉化版的可能有各种奇怪的问题。建议用IDEA英文版&#xff0c;卸载重装。 2、下载maven&#xff0c;配置环…

2024HW|常见红队使用工具

目录 什么是HW&#xff1f; 什么是网络安全红蓝对抗&#xff1f; 红队 常见工具 信息收集工具 Nmap 简介 漏洞扫描工具 Nessus简介 AWVS 简介 抓包工具 Wireshark简介 TangGo 简介 web 应用安全工具 Burpsuite 简介 SQLMap webshell 管理工具 蚁剑 冰蝎 后…

《PNAS》和《Nature Communications》仿章鱼和蜗牛的粘液真空吸附,赋予了机器人吸盘新的“超能力”

想象一下&#xff0c;如果机器人能够像章鱼一样牢牢吸附在粗糙崎岖的岩石上&#xff0c;或者像蜗牛那样在墙面上悠然负重爬行&#xff0c;那会是多么神奇的一幕&#xff01;近日&#xff0c;布里斯托大学机器人实验室的Jonathan Rossiter教授课题组就为我们带来了这样的“超能力…

Fastjson 反序列化漏洞[1.2.24-rce]

漏洞复现环境搭建请参考 http://t.csdnimg.cn/vSaaw kali切换jdk版本请参考 Kali安装JAVA8和切换JDK版本的详细过程_kali安装jdk8-CSDN博客 漏洞原理 Fastjson提供的com.sun.rowset.JdbcRowSetImpl类下的dataSourceName方法支持传入一个RMI/LDAP源&#xff0c;支持远程调用。…

绘唐2AI工具在哪里下载

绘唐2AI工具在哪里下载 激活授权方式&#xff1a;https://qvfbz6lhqnd.feishu.cn/wiki/CcaewIWnSiAFgokOwLycwi0Encf 绘唐2AI工具是一款由中国国家语言资源监测与研究中心开发的人工智能绘画工具。该工具利用深度学习算法和人工智能技术&#xff0c;能够自动将输入的文字描述转…

【MySQL数据库】:MySQL内置函数

目录 日期函数 current_date 函数 current_time 函数 current_timestamp 函数 now 函数 date 函数 date_add 函数 date_sub 函数 datediff 函数 字符串函数 charset 函数 concat 函数 instr 函数 ucase 函数 lcase 函数 left 函数 length 函数 replace…

探索自动发邮件的奥秘:从配置到实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;邮件自动化的魅力 二、配置环境&#xff1a;选择适合的SMTP服务器 示…

Spring Boot集成freemaker快速入门demo

1.什么是freemaker&#xff1f; FreeMarker 是一款模板引擎&#xff1a;即一种基于模板和要改变的数据&#xff0c;并用来生成输出文本(HTML网页&#xff0c;电子邮件&#xff0c;配置文件&#xff0c;源代码等)的通用工具。 它不是面向最终用户的&#xff0c;而是一个Java类库…

Adobe AntiCC 简化版 安装教程

Adobe AntiCC 简化版 安装教程 原文地址&#xff1a;https://blog.csdn.net/weixin_48311847/article/details/139277743

数据真实性与经济收益的矛盾:第三方检测何去何从|中联环保圈

在当今的市场化竞争环境中&#xff0c;第三方检测公司在环保行业中处于较为底端的位置。其多数检测业务依赖于第三方技术服务单位的委托&#xff0c;然而在委托过程中&#xff0c;往往面临着报告真实性和收款的矛盾。一旦第三方检测公司负责人在数据真实性和经济收益矛盾中取舍…

1806 jsp防疫物资销售管理系统 Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 防疫物资销售管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助采用了java设计&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统采用web模式&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.…

Android USB调试模式下自动上下滑动(Go实现)

简介 有的时候要对手机UI界面进行滑动测试&#xff0c; 手动或许太消耗时间&#xff0c; 理由Android USB调试模式对UI进行上下滑动测试。 adb指令 使用adb --help 可以查看所有的adb支持指令, 但这里我们只需要上下, 使用到的指令&#xff1a; adb devices #列举所有设备 ad…

不同类型的区块链钱包有什么特点和适用场景?

区块链钱包是用于存储和管理加密货币的重要工具&#xff0c;市面上有许多不同类型的区块链钱包可供选择。以下是几种主要类型的区块链钱包及其特点和适用场景。 1.软件钱包&#xff1a; 特点&#xff1a;软件钱包是最常见的一种区块链钱包&#xff0c;通常作为软件应用程序提供…

后量子加密算法的数学原理

后量子加密算法是一类专为抵御量子计算机攻击而设计的加密算法。随着量子计算技术的迅速发展&#xff0c;传统的加密算法如RSA和椭圆曲线密码学在量子计算机面前变得脆弱&#xff0c;因此&#xff0c;开发能够在量子计算时代保持安全性的加密算法变得尤为重要。下面将详细介绍后…

软件架构设计之质量属性浅析

引言 在数字化浪潮席卷而来的今天&#xff0c;软件已经渗透到我们生活的方方面面&#xff0c;从手机APP到大型企业级系统&#xff0c;无一不彰显着软件技术的魅力。然而&#xff0c;在这背后&#xff0c;软件架构设计作为软件开发的基石&#xff0c;其质量属性的重要性不言而喻…