Unity 游戏开发:C# 脚本、物理与动画系统
Unity 3D 游戏开发从入门到实战
C# 脚本、物理与动画系统权威指南
本教程面向零基础初学者,通过系统讲解 Unity 的核心机制——C# 脚本驱动、物理仿真和动画控制,带你快速掌握 3D 游戏开发的基本功。我们将理论结合实战,最终完成一个可玩的平台跳跃 Demo。
一、开发环境与 C# 脚本入门
1.1 安装 Unity Hub 与编辑器版本选择
- 访问 unity.com 下载 Unity Hub,它用于管理引擎版本和项目。
- 在 Hub 中安装 Unity 2022 LTS 或更高版本(长期支持版稳定性最佳)。
- 安装时勾选模块:Microsoft Visual Studio(或 VS Code)、WebGL Build Support(可选)、Windows/Mac/Linux Build Support。
1.2 创建你的第一个项目
- 打开 Hub,点击“新建项目”,选择 3D 核心模板。
- 命名项目为
PlatformerTutorial,选择存储路径,创建。 - 界面速览:
- Scene 视图:可视化编辑场景。
- Game 视图:运行时预览。
- Hierarchy:场景对象层级。
- Project:资源文件管理。
- Inspector:选中对象的属性面板。
1.3 C# 脚本与 MonoBehaviour
Unity 中几乎所有逻辑都通过 C# 脚本实现。脚本必须继承自 MonoBehaviour 才能挂载到 GameObject 上。
创建一个 C# 脚本:
- 在 Project 窗口右键 → Create → C# Script,命名为
PlayerController。 - 双击脚本,会自动用编辑器打开。
基础模板:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// Start 在第一次帧更新之前调用
void Start()
{
Debug.Log("游戏开始!");
}
// Update 每帧调用一次
void Update()
{
// 检测玩家输入
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("空格键被按下");
}
}
}
将脚本拖拽到场景中的 Main Camera 或新建空物体上,运行即可看到控制台输出。
1.4 核心 API 速查
- 获取/操作自身变换:
transform.position、transform.rotation、transform.Translate(Vector3.forward * speed * Time.deltaTime) - 获取组件:
Rigidbody rb = GetComponent<Rigidbody>(); - 输入系统:
Input.GetAxis("Horizontal")返回 -1 到 1 的浮点值,用于键盘方向。 - 实例化与销毁:
Instantiate(prefab, position, rotation)、Destroy(gameObject, delay)。
二、Unity 物理系统深度解析
物理引擎(PhyX)负责模拟真实世界的运动与碰撞,核心组件为 Rigidbody 和 Collider。
2.1 刚体 (Rigidbody) 与施加力
给物体添加 Rigidbody 组件后,它就会受重力影响,能对力做出反应。
移动一个物理对象的最佳实践:不使用 Transform 直接修改位置,而是通过 Rigidbody 的力或速度。
public class PhysicsMovement : MonoBehaviour
{
public float moveForce = 10f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate() // 物理更新使用 FixedUpdate,保持与时间步一致
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(h, 0, v).normalized;
rb.AddForce(movement * moveForce);
}
}
FixedUpdate调用频率固定(默认 0.02秒),所有物理计算应在此执行。AddForce默认应用于物体质心,可产生加速效果。- 如果要直接控制速度,可设置
rb.velocity。
2.2 碰撞器 (Collider) 与触发器 (Trigger)
碰撞器定义了物体的物理轮廓,常见形状有 Box、Sphere、Capsule 等。
- 碰撞事件:需要两个物体都有 Collider,且至少一个带 Rigidbody。
脚本中实现OnCollisionEnter、OnCollisionStay、OnCollisionExit。 - 触发器事件:勾选 Collider 的
Is Trigger属性后,不再产生物理碰撞,而是发送OnTriggerEnter等消息,常用于检测区域、吃金币。
示例:收集金币
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Coin"))
{
Destroy(other.gameObject);
score++;
}
}
2.3 物理材质 (Physics Material)
创建物理材质调整摩擦力与弹性:
- Project 右键 → Create → Physic Material,命名为
Slippery。 - Dynamic Friction:移动时的摩擦力,0 代表冰面效果。
- Static Friction:静止时的摩擦力。
- Bounciness:弹性(0 无弹跳,1 完全弹性)。
将材质拖到 Collider 的Material插槽上即可应用。
2.4 射线检测 (Raycast)
从一点发射射线,检测是否碰到物体。常用于射击、视野、地面检测。
void Update()
{
Ray ray = new Ray(transform.position, transform.forward);
if (Physics.Raycast(ray, out RaycastHit hit, 10f))
{
Debug.Log("命中物体: " + hit.collider.name);
}
}
参数:起点、方向、命中信息、最大距离、图层遮罩(可选)。
三、Unity 动画系统完全掌握
动画系统由 Animator 组件驱动,依赖 Animator Controller 资源,通过状态机管理动画剪辑的过渡。
3.1 动画剪辑与 Animator Controller
- 导入模型(如 FBX 带骨骼动画)后,动画剪辑会自动提取。
- 在 Project 右键 → Create → Animator Controller,命名为
PlayerAnimController。 - 将该 Controller 拖到模型/预制体的 Animator 组件上。
- 双击 Controller 打开 Animator 窗口,会看到默认状态 Any State、Entry 等。
3.2 动画状态机与过渡
- 将动画剪辑(如 Idle, Walk, Jump)拖入 Animator 窗口成为状态。
- 右键某个状态 → Set as Layer Default State(设置初始状态)。
- 创建过渡:右键状态 → Make Transition,连线到目标状态。
- 单击过渡线,在 Inspector 中取消 Has Exit Time,勾选 Conditions,添加条件(如参数 Bool
isWalking为 true)。
3.3 动画参数与脚本控制
在 Animator 窗口左栏 Parameters 面板添加:
- Bool:表示持续状态(是否蹲下)
- Float:用于混合树(速度值)
- Trigger:一次性触发(跳跃)
控制代码示例:
private Animator anim;
private Rigidbody rb;
void Start()
{
anim = GetComponent<Animator>();
rb = GetComponent<Rigidbody>();
}
void Update()
{
float speed = new Vector3(rb.velocity.x, 0, rb.velocity.z).magnitude;
anim.SetFloat("Speed", speed); // 假设 Animator 中有 Float 参数 Speed
if (Input.GetButtonDown("Jump") && IsGrounded())
{
anim.SetTrigger("JumpTrigger");
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
- 使用
SetFloat、SetBool、SetTrigger驱动动画切换。 - 混合树 (Blend Tree):在 Animator 中创建 Blend Tree 状态,根据 Float 参数融合 Idle 和 Walk 动画。
3.4 根运动 (Root Motion) 与人形动画
Root Motion:动画本身的位移应用到物体上,使移动更自然。
启用方法:
- 选中动画剪辑,在 Inspector 中勾选
Root Motion(若动画内含根位移)。 - 在 Animator 组件中同样勾选
Apply Root Motion。 - 脚本中控制移动时,建议结合
anim.deltaPosition或直接使用CharacterController。
对于人形骨骼(Humanoid),使用 Unity 的 Avatar 系统可以重定向同类型骨骼的动画,实现动画复用。
四、实战:3D 平台跳跃 Demo
我们将结合以上知识,制作一个能跑、跳、拾取金币的简单角色。
4.1 场景搭建
- 创建平面
Plane作为地面,Scale 放大 5 倍。 - 创建几个 Box/Cylinder 作为障碍和平台。
- 创建 Sphere 作为金币,设置 Collider 为 Is Trigger,添加标签
Coin。 - 新建空物体
Player,添加Capsule Collider、Rigidbody(锁定旋转 X/Z 防止摔倒),再添加挂载脚本PlayerController。
4.2 编写 PlayerController(物理移动 + 动画)
[RequireComponent(typeof(Rigidbody), typeof(Animator))]
public class PlayerController : MonoBehaviour
{
[Header("移动参数")]
public float moveSpeed = 5f;
public float jumpForce = 8f;
public LayerMask groundLayer;
private Rigidbody rb;
private Animator anim;
private bool isGrounded;
void Awake()
{
rb = GetComponent<Rigidbody>();
anim = GetComponent<Animator>();
}
void Update()
{
// 地面检测(短程射线向下)
isGrounded = Physics.Raycast(transform.position, Vector3.down, 1.1f, groundLayer);
if (isGrounded && Input.GetButtonDown("Jump"))
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
anim.SetTrigger("Jump");
}
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 moveDir = new Vector3(h, 0, v).normalized;
// 移动
rb.MovePosition(transform.position + moveDir * moveSpeed * Time.deltaTime);
// 转向
if (moveDir != Vector3.zero)
transform.forward = moveDir;
// 动画参数(混合树使用 Speed)
anim.SetFloat("Speed", moveDir.magnitude);
anim.SetBool("IsGrounded", isGrounded);
}
}
- 使用
MovePosition替代直接修改position,保持物理插值流畅。 - 如果使用 Root Motion 则需调整移动逻辑。
4.3 金币收集脚本
public class CoinPickup : MonoBehaviour
{
private static int coinCount;
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
coinCount++;
Debug.Log($"金币: {coinCount}");
Destroy(gameObject);
}
}
}
4.4 动画配置简要清单
- 创建 Run、Idle、Jump 动画剪辑(可使用 Mixamo 免费模型与动画)。
- 创建 Blend Tree 命名为
Locomotion,混合 Idle 和 Run,使用 Float 参数Speed。 - 添加 Jump 状态,通过 Trigger
Jump从 Any State 或 Locomotion 过渡,设置合理退出时间或添加过渡回 Idle。 - 添加布尔参数
IsGrounded,在跳跃落地过渡条件中使用。
运行游戏:控制角色移动,按空格跳跃,收集金币,动画应正确切换。
结语与进阶方向
通过本教程,你已经掌握了 Unity 最核心的三大支柱:
- C# 脚本驱动交互逻辑
- 物理系统实现真实运动与碰撞
- 动画系统赋予角色生命力
接下来可探索的方向:
- UI 系统:显示分数、生命值
- 音效与特效:增强反馈
- 敌人 AI:NavMesh 导航与简单行为状态机
- 场景管理与关卡设计:ProBuilder 快速建模
现在,启动你的 Unity,开始打造属于自己的游戏世界吧!