Unity基础学习(七)最小单位Gameobject的介绍

目录

一、GameObject是什么

二、GameObject中的成员属性及变量

(1)修改名字

(2)打印里面包含的激活状态 

​编辑(3)静态属性的修改 ,注意看这里打上了√

(4) 打印层级和标签信息

(5) 打印transform中的信息

(6) 父对象失活对子对象的影响

三、GameObject中的静态方法

(1)CreatePrimitive​

(2) Find("Name")​​

(3)FindGameObjectWithTag("Tag")​​

(4​)FindGameObjectsWithTag("Tag")​

(5) FindObjectOfType()​​

(6)Instantiate​

(7)Destroy​

(8)DontDestroyOnLoad​

小结:

①基础几何体创建与组件操作

②对象查找方法与限制

③ 对象克隆与销毁机制

④ 跨场景对象生命周期控制

⑤Unity 与 C# 对象系统差异

四、GameObject中的成员方法


一、GameObject是什么

        GameObject是Unity场景中所有实体的基础容器,代表场景中的一个独立对象。就像下面一样,我创建了一个空对象,最右侧的Insoector面板上面显示的就是这个对象的基本内容,它包含了一些最基本的识别编号,他是作为其他组件的挂载池,是最最基本的组件。本质来说他也是组件,是组件,就会有自己的属性,成员变量,以及成员方法,所以我们来看看它有哪些内容。

其核心特性包括:

  1. 组件容器​:本身无功能,需挂载组件(如Transform、脚本、Collider等)实现具体行为。
  2. 层级结构​:通过Transform组件形成父子层级,实现对象间的相对坐标和批量控制。
  3. 生命周期​:由引擎管理创建、激活、销毁等状态,与场景加载/卸载紧密相关。
  4. 唯一标识​:每个GameObject具有唯一实例ID,可通过名称(name)或标签(tag)访问。

二、GameObject中的成员属性及变量

属性/变量作用注意事项代码示例
name对象名称标识(可重复)修改后会影响Find方法的结果gameObject.name = "Player";
activeSelf自身激活状态(不受父对象影响)直接控制对象显隐,但父对象失活时仍不可见bool isActive = gameObject.activeSelf;
activeInHierarchy实际激活状态(受父对象链影响)只读属性,反映对象在场景中的真实可见性if (gameObject.activeInHierarchy) { }
isStatic标记为静态对象(参与光照烘焙等优化)运行时修改可能导致性能开销gameObject.isStatic = true;
layer所属层级(0-31)需配合LayerMask使用,常用于射线检测或摄像机过滤gameObject.layer = 8;
tag标签分类优先用CompareTag替代字符串比较if (gameObject.tag == "Enemy") { }
transform控制位置、旋转、父子关系修改时会触发物理引擎更新Vector3 pos = gameObject.transform.position;

关于上面的属性的演示说明:

(1)修改名字

// 1. 修改本对象名称
        this.gameObject.name = "ModifiedObject";
        Debug.Log("当前对象名称: " + gameObject.name);

可见成功修改 

(2)打印里面包含的激活状态 

// 2. 打印激活状态
Debug.Log("--- 激活状态 ---");
Debug.Log("activeSelf: " + gameObject.activeSelf);
Debug.Log("activeInHierarchy: " + gameObject.activeInHierarchy);

(3)静态属性的修改 ,注意看这里打上了√

// 3. 打印静态标记状态
gameObject.isStatic = true; // 设置静态标记(实际项目慎用)
Debug.Log("--- 静态状态 ---");
Debug.Log("isStatic: " + gameObject.isStatic);

 

(4) 打印层级和标签信息

// 4. 打印层级信息
gameObject.layer = LayerMask.NameToLayer("UI"); // 设置层级
Debug.Log("--- 层级信息 ---");
Debug.Log("Layer数值: " + gameObject.layer);
Debug.Log("Layer名称: " + LayerMask.LayerToName(gameObject.layer));

// 5. 打印标签信息
Debug.Log("--- 标签信息 ---");
Debug.Log("当前标签: " + gameObject.tag);
Debug.Log("是否Player标签: " + gameObject.CompareTag("Player"));

 

(5) 打印transform中的信息

// 6. 打印变换组件信息
Debug.Log("--- 变换信息 ---");
Debug.Log("位置: " + transform.position);
Debug.Log("旋转: " + transform.rotation.eulerAngles);
Debug.Log("缩放: " + transform.localScale);

 

(6) 父对象失活对子对象的影响

// 7. 父对象激活状态影响演示
GameObject parentObj = new GameObject("ParentObject");
transform.SetParent(parentObj.transform);

Debug.Log("--- 父子关系测试 ---");
Debug.Log("父对象激活前 activeInHierarchy: " + gameObject.activeInHierarchy);
parentObj.SetActive(false);
Debug.Log("父对象激活后 activeInHierarchy: " + gameObject.activeInHierarchy);

这就像小时候,你家长要睡觉了,非要让你也睡觉 

 

三、GameObject中的静态方法

方法作用注意事项代码示例
CreatePrimitive创建基本几何体默认无碰撞体(如不需要可手动移除)GameObject.CreatePrimitive(PrimitiveType.Sphere);
Find("Name")按名称查找单个激活对象效率低,避免在Update中频繁调用GameObject obj = GameObject.Find("Cube");
FindGameObjectWithTag("Tag")按标签查找单个激活对象需预先在标签管理器中定义标签GameObject player = GameObject.FindGameObjectWithTag("Player");
FindGameObjectsWithTag("Tag")按标签查找所有激活对象返回数组,需判空处理GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
FindObjectOfType<T>()查找挂载某类型脚本的激活对象无法查找禁用脚本Camera cam = GameObject.FindObjectOfType<Camera>();
Instantiate(original)克隆对象或预制体高频调用需优化(如对象池)GameObject clone = GameObject.Instantiate(prefab);
Destroy(obj)销毁对象或组件延迟到帧末尾执行,DestroyImmediate慎用GameObject.Destroy(enemy, 3.0f); //3秒后销毁
DontDestroyOnLoad(obj)跨场景保留对象需手动管理生命周期GameObject.DontDestroyOnLoad(gameObject);

逐个解释:

(1)CreatePrimitive

作用​:创建自带基础几何体的GameObject
注意事项​:默认自带碰撞体,无刚体,需手动添加Rigidbody组件
支持几何体类型​(PrimitiveType枚举):

几何体类型描述
Cube立方体
Sphere球体
Capsule胶囊体
Cylinder圆柱体(旧版)
Plane平面(大尺寸地面)
Quad四边形(小尺寸面片)

        看,作为造世主的你创建了一个球。值得注意的是,你的脚本必选先挂载到场景上的某一个对象上才能执行 

 // 创建球体并设置位置
 GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

(2) Find("Name")​

作用​:通过名称查找单个激活对象
注意事项​:全局遍历效率低,避免高频调用
代码示例​:

// 查找名为 "Player" 的对象
GameObject player = GameObject.Find("Player");

if (player != null) {
    Debug.Log("找到玩家对象: " + player.name);
    player.transform.position = Vector3.zero; // 重置位置
} else {
    Debug.LogWarning("未找到玩家对象");
}

(3)FindGameObjectWithTag("Tag")​

作用​:通过标签查找单个激活对象
注意事项​:需在标签管理器预定义标签
代码示例​:

// 查找标签为 "Enemy" 的单个对象
GameObject enemy = GameObject.FindGameObjectWithTag("Enemy");

if (enemy != null) {
    Debug.Log("发现敌人: " + enemy.name);
}

(4)FindGameObjectsWithTag("Tag")​

作用​:通过标签查找所有激活对象们,这个就是上面的多个情况
注意事项​:返回数组需判空或检查长度。如果场景中 存在多个满足条件的对象,我们无法准确确定知道的是谁
代码示例​:

// 查找所有标签为 "Item" 的对象
        GameObject[] items = GameObject.FindGameObjectsWithTag("Item");
        
        if (items.Length > 0)
        {
            Debug.Log("找到 " + items.Length + " 个可拾取物品");
            foreach (GameObject item in items)
            {
                item.SetActive(false); // 隐藏所有物品
            }
        }

(5) FindObjectOfType()​

作用​:查找场景中挂载某类型脚本的激活对象
注意事项​:无法查找禁用脚本
代码示例​:

// 查找场景中第一个激活的摄像机
Camera mainCamera = GameObject.FindObjectOfType<Camera>();

if (mainCamera != null) {
    mainCamera.backgroundColor = Color.blue; // 修改背景颜色
}

 

(6)Instantiate

作用​:克隆预制体或场景对象 实例化对象 它的作用是根据GameObject对象 创建出一个和他一模一样的GameObject对象
注意事项​:高频调用需用对象池优化
代码示例​:

GameObject objClone = GameObject.Instantiate(myObj);

(7)Destroy

作用​:延迟销毁对象或组件
注意事项​:

删除对象有两种作用
1.是删除指定的一个游戏对象
2.是删除一个指定的脚本对象
注意:这个Destroy的方法 不会马上移除对象 只是给这个对象加了一个移除标识
      一般情况下 他会在下一帧时把这个对象移除并从内存中移除

下面这个方法就是立即把对象从内存中移除了  
GameObject.DestroyImmediate(objClone);
没有特殊需求 就是一定要马上移除一个对象的话
建议使用上面的Destroy方法 因为是异步的 降低卡顿的几率
如果是继承MonoBehavior的类 不用再写GameObject
直接调用函数
代码示例​:

 // 3秒后销毁本对象
        Destroy(gameObject, 3.0f); 
        
        // 仅销毁脚本组件(保留GameObject)
        // Destroy(this); 

(8)DontDestroyOnLoad

作用​:跨场景保留对象
注意事项​:需手动管理生命周期

默认情况 在切换场景时 场景中对象都会被自动删除掉
如果你希望某个对象再过场景的时候不被移除 就使用下面这个方法
下面这句代码的意思就是 自己依附的GameObject对象在过场景的时候不被移除
一般都是传依附的GameObject对象

代码示例​:

GameObject.DontDestroyOnLoad(this.gameObject);

小结:


①基础几何体创建与组件操作

        通过 GameObject.CreatePrimitive 方法可快速生成基础几何体(立方体、球体等),生成的对象默认包含网格渲染器和碰撞体组件。创建后需注意:

可手动移除不需要的碰撞体组件以优化性能

通过 GetComponent 获取对象上的任意脚本或组件进行后续操作

动态添加新组件使用 AddComponent,例如为对象添加刚体实现物理效果


②对象查找方法与限制

Unity 提供多种对象查找方式,核心方法包括:

按名称查找​:GameObject.Find 全局遍历场景对象,效率较低

按标签查找​:FindGameObjectWithTag(单个)和 FindGameObjectsWithTag(多个),需预定义标签

  • 按脚本查找​:FindObjectOfType 遍历场景中激活的脚本实例
    共同限制:无法查找失活对象,存在多个匹配对象时返回结果不确定,高频调用需用缓存优化

③ 对象克隆与销毁机制

使用 Instantiate 克隆对象时会完整复制原对象的所有组件和子对象:

适合生成敌人、子弹等动态对象

高频克隆需配合对象池技术避免性能问题
销毁操作通过 Destroy 实现:

默认延迟到帧末尾异步执行,避免卡顿

DestroyImmediate 立即移除对象,但易导致空引用问题

可指定销毁延迟时间,例如 Destroy(obj, 5.0f)


④ 跨场景对象生命周期控制

通过 DontDestroyOnLoad 方法保留对象跨场景:

常用于全局管理对象如音效控制器、游戏存档

需配合单例模式防止重复创建

手动管理保留对象的销毁时机,避免内存泄漏


⑤Unity 与 C# 对象系统差异

UnityEngine.Object 继承自 C# 的 System.Object,包含 Unity 特有的资源管理逻辑

Unity 对象销毁为标记移除,实际内存回收由引擎管理

静态方法如 Destroy 可直接调用,无需通过 GameObject 类名

Unity里面的Object 不是指的万物之父object
Unity里的Object 命名空间在UnityEngine.Object类 也是继承万物之父的一个自定义类
C#中的Object 命名空间是System中的

四、GameObject中的成员方法

方法作用注意事项代码示例
AddComponent<T>()动态添加组件或脚本不可添加重复组件Rigidbody rb = gameObject.AddComponent<Rigidbody>();
SetActive(bool)激活/禁用对象禁用后停止所有组件更新(如UpdategameObject.SetActive(false); //隐藏对象
CompareTag("Tag")安全比较标签避免拼写错误,性能优于字符串比较if (gameObject.CompareTag("Player")) { }
SendMessage("MethodName")调用对象所有脚本的指定方法反射调用性能较差,优先用组件直接访问gameObject.SendMessage("TakeDamage", 10);
BroadcastMessage("MethodName")向自身及子对象发送消息可能引发意外副作用gameObject.BroadcastMessage("Respawn");
SendMessageUpwards("MethodName")向自身及父对象发送消息慎用,易导致循环调用gameObject.SendMessageUpwards("ApplyGravity");

        123都不用讲了,这个方法很容易就理解了,我们来看看后面三个方法 ,一般来说,用处不大,除非你有什么特殊需求。

//通过广播或者发送消息的形式 让别人或者自己 执行某些行为的方法

//通知自己 执行什么行为
//命令自己 去执行这个TestFun这个函数 会在自己身上挂载的所有脚本中去找这个名字的函数
this.gameObject.SendMessage("TestFun");
//会把自己身上的所有脚本中的TestFun函数都执行一遍 别的脚本也会执行 所有脚本中有这个名字的函数去执行
//名字加参数可以直接放在括号里面   this.gameObject.SendMessage("TestFun",154);

//广播行为 让自己和自己的子物体都执行这个函数
this.gameObject.BroadcastMessage("TestFun");

//向父对象和自己发送信息 并执行
this.gameObject.SendMessageUpwards("函数名");
 

没啦,就这样,下期见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FAREWELL00075

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值