Appearance
游戏对象与组件系统
基础概念
你可以先把 Unity 的游戏对象与组件系统理解成一句话:
Unity 里的每一个东西都是一个 GameObject,但 GameObject 本身几乎什么都不会做;它靠身上挂的 Component 获得能力。
比如一个玩家角色不是“一个玩家类”,而是:
c
Player GameObject
├─ Transform 位置、旋转、缩放
├─ SpriteRenderer 负责显示图片
├─ Rigidbody2D 负责物理运动
├─ Collider2D 负责碰撞范围
├─ Animator 负责动画
├─ AudioSource 负责播放声音
└─ PlayerController 你自己写的控制脚本这就是 Unity 的核心思想:组合,而不是单纯继承。
1. GameObject 是“对象容器”
GameObject 可以理解为场景里的一个实体。
它可以是:
- 玩家
- 敌人
- 摄像机
- 灯光
- 子弹
- 地面
- UI 按钮
- 一个空对象
- 一个看不见的出生点
- 一个管理游戏逻辑的对象
注意:GameObject 不一定看得见。
比如你创建一个空对象 GameObject > Create Empty,它在游戏画面里什么都不显示,但它可以作为:
- 出生点
- 摄像机跟随目标
- 物体分组
- 脚本管理器
- 音效播放器
- 关卡控制器
所以别把 GameObject 理解成“模型”或“图片”,它更像是 Unity 世界里的“一个节点”。
2. Component 是“能力模块”
Component 是挂在 GameObject 上的功能。
一个 GameObject 能做什么,取决于它挂了哪些组件。
举个最典型的例子:你创建一个 Cube,它默认会有这些组件:
Cube
├─ Transform
├─ Mesh Filter
├─ Mesh Renderer
└─ Box Collider它们分别负责:
| 组件 | 作用 |
|---|---|
Transform | 决定位置、旋转、缩放 |
Mesh Filter | 决定这个物体用什么模型形状 |
Mesh Renderer | 决定这个物体怎么被渲染出来 |
Box Collider | 给它一个盒子形状的碰撞体 |
如果你删掉 Mesh Renderer,Cube 还在,但看不见了。 如果你删掉 Box Collider,Cube 还看得见,但不能正常参与碰撞。 如果你加一个 Rigidbody,它就会受到重力和物理影响。
这就是组件系统的威力:通过加组件、删组件、调参数,改变对象能力。
3. Transform 是最特殊、最重要的组件
每个 GameObject 都必定有 Transform,删不掉。
它负责三件事:
c
Position 位置
Rotation 旋转
Scale 缩放在 3D 里是:
c
X:左右
Y:上下
Z:前后常见代码:
c
transform.position = new Vector3(0, 1, 0);
transform.rotation = Quaternion.Euler(0, 90, 0);
transform.localScale = new Vector3(2, 2, 2);其中 transform 是当前脚本所挂载对象的 Transform。
例如脚本挂在 Player 上:
c
transform.position += new Vector3(1, 0, 0);意思就是:让 Player 往右移动一点。
4. 父子关系:Hierarchy 层级系统
Unity 左侧的 Hierarchy 面板,本质上就是 GameObject 的父子树。
比如:
c
Player
├─ Body
├─ Weapon
└─ NameText如果 Weapon 是 Player 的子对象,那么 Player 移动时,Weapon 会跟着移动。
这里有两个非常重要的概念:
| 属性 | 含义 |
|---|---|
position | 世界坐标 |
localPosition | 相对父对象的坐标 |
比如:
c
Player position = (10, 0, 0)
Weapon localPosition = (1, 0, 0)那么 Weapon 的世界位置大概就是:
c
(11, 0, 0)初学者一定要掌握这个: 子对象的位置、旋转、缩放会受到父对象影响。
5. 脚本也是组件
你自己写的 C# 脚本,只要继承 MonoBehaviour,它就是一个可以挂到 GameObject 上的组件。
例如:
c
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 5f;
void Update()
{
float x = Input.GetAxis("Horizontal");
transform.position += new Vector3(x, 0, 0) * speed * Time.deltaTime;
}
}这个脚本本身不会自动运行。 你必须把它挂到某个 GameObject 上,比如 Player。
挂上去之后:
c
Player
├─ Transform
├─ SpriteRenderer
├─ Rigidbody2D
└─ PlayerController这时 Player 就获得了“接收输入并移动”的能力。
6. 组件之间怎么互相访问
一个对象身上可能有很多组件,脚本经常需要访问它们。
比如 Player 身上有 Rigidbody2D,你想在脚本里控制它:
c
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Rigidbody2D rb;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
float x = Input.GetAxis("Horizontal");
rb.linearVelocity = new Vector2(x * 5f, rb.linearVelocity.y);
}
}核心就是这句:
c
rb = GetComponent<Rigidbody2D>();意思是: 从当前 GameObject 身上拿到 Rigidbody2D 组件。
常见获取方式:
| 方法 | 用途 |
|---|---|
GetComponent<T>() | 获取自己身上的组件 |
GetComponentInChildren<T>() | 获取子对象里的组件 |
GetComponentInParent<T>() | 获取父对象里的组件 |
| Inspector 拖拽引用 | 最推荐新手使用 |
Find() | 能用,但不建议经常用 |
7. Inspector 是组件参数编辑器
右侧 Inspector 面板就是查看和修改组件的地方。
比如你的脚本这样写:
c
public float speed = 5f;或者:
c
[SerializeField] private float speed = 5f;Unity Inspector 里就会出现一个 Speed 参数。
这意味着你不用改代码,也能在 Unity 里调整速度。
推荐新手多用:
c
[SerializeField] private float speed = 5f;它的好处是: 代码里保持私有,Inspector 里还能调参数。
8. 一个完整例子:玩家对象
假设你要做一个 2D 玩家,应该这样组合:
c
Player
├─ Transform
├─ SpriteRenderer
├─ Rigidbody2D
├─ CapsuleCollider2D
├─ Animator
└─ PlayerController每个组件负责一块:
| 组件 | 负责 |
|---|---|
Transform | 玩家在哪里 |
SpriteRenderer | 玩家长什么样 |
Rigidbody2D | 玩家怎么受物理影响 |
CapsuleCollider2D | 玩家碰撞范围 |
Animator | 玩家跑、跳、站立动画 |
PlayerController | 玩家输入、移动、跳跃逻辑 |
这就是 Unity 的正确思维: 不要把所有功能都写进一个超大的脚本,而是让不同组件负责不同能力。
9. 新手最容易混的几个点
GameObject 和 Component 不是一回事。 GameObject 是对象,Component 是对象身上的功能。
Transform 不是“位置属性”,它是一个组件。 只是这个组件里面包含 position、rotation、scale。
脚本不是独立运行的程序。 脚本要挂到 GameObject 上,才会随着 Unity 生命周期运行。
看不见的对象也很有用。 空 GameObject 常用来做管理器、出生点、父级容器、摄像机目标。
一个对象不要什么都负责。 比如 GameManager 不应该同时控制玩家移动、敌人 AI、UI、音效、存档。要拆开。
10. 你应该怎么练
建议你按这个顺序练:
- 创建一个 Cube,观察它默认有哪些组件。
- 删除
Mesh Renderer,看看它为什么消失。 - 给 Cube 添加
Rigidbody,看看它为什么会掉下去。 - 创建 Empty GameObject,理解“看不见的对象”。
- 创建父子对象,移动父对象,观察子对象跟随。
- 写一个脚本控制物体移动。
- 用
GetComponent获取组件。 - 用
[SerializeField]在 Inspector 里调参数。 - 做一个简单 Player:显示、移动、碰撞、跳跃。
- 把 Player 做成 Prefab,拖出来复用。
最核心的一句话你一定要记住:
GameObject 负责“是谁”,Component 负责“能做什么”,Transform 负责“在哪里”。
把这三个东西吃透,你就真正入门 Unity 了。
参考链接
对象与组件系统