Unity 游戏开发:C# 脚本、物理与动画系统

FreeGuideOnline 最新 2026-06-12

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 创建你的第一个项目

  1. 打开 Hub,点击“新建项目”,选择 3D 核心模板
  2. 命名项目为 PlatformerTutorial,选择存储路径,创建。
  3. 界面速览:
    • Scene 视图:可视化编辑场景。
    • Game 视图:运行时预览。
    • Hierarchy:场景对象层级。
    • Project:资源文件管理。
    • Inspector:选中对象的属性面板。

1.3 C# 脚本与 MonoBehaviour

Unity 中几乎所有逻辑都通过 C# 脚本实现。脚本必须继承自 MonoBehaviour 才能挂载到 GameObject 上。

创建一个 C# 脚本:

  1. Project 窗口右键 → Create → C# Script,命名为 PlayerController
  2. 双击脚本,会自动用编辑器打开。

基础模板:

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.positiontransform.rotationtransform.Translate(Vector3.forward * speed * Time.deltaTime)
  • 获取组件Rigidbody rb = GetComponent<Rigidbody>();
  • 输入系统Input.GetAxis("Horizontal") 返回 -1 到 1 的浮点值,用于键盘方向。
  • 实例化与销毁Instantiate(prefab, position, rotation)Destroy(gameObject, delay)

二、Unity 物理系统深度解析

物理引擎(PhyX)负责模拟真实世界的运动与碰撞,核心组件为 RigidbodyCollider

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。
    脚本中实现 OnCollisionEnterOnCollisionStayOnCollisionExit
  • 触发器事件:勾选 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

  1. 导入模型(如 FBX 带骨骼动画)后,动画剪辑会自动提取。
  2. 在 Project 右键 → Create → Animator Controller,命名为 PlayerAnimController
  3. 将该 Controller 拖到模型/预制体的 Animator 组件上。
  4. 双击 Controller 打开 Animator 窗口,会看到默认状态 Any StateEntry 等。

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);
    }
}
  • 使用 SetFloatSetBoolSetTrigger 驱动动画切换。
  • 混合树 (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 场景搭建

  1. 创建平面 Plane 作为地面,Scale 放大 5 倍。
  2. 创建几个 Box/Cylinder 作为障碍和平台。
  3. 创建 Sphere 作为金币,设置 Collider 为 Is Trigger,添加标签 Coin
  4. 新建空物体 Player,添加 Capsule ColliderRigidbody(锁定旋转 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 动画配置简要清单

  1. 创建 Run、Idle、Jump 动画剪辑(可使用 Mixamo 免费模型与动画)。
  2. 创建 Blend Tree 命名为 Locomotion,混合 Idle 和 Run,使用 Float 参数 Speed
  3. 添加 Jump 状态,通过 Trigger Jump 从 Any State 或 Locomotion 过渡,设置合理退出时间或添加过渡回 Idle。
  4. 添加布尔参数 IsGrounded,在跳跃落地过渡条件中使用。

运行游戏:控制角色移动,按空格跳跃,收集金币,动画应正确切换。


结语与进阶方向

通过本教程,你已经掌握了 Unity 最核心的三大支柱:

  • C# 脚本驱动交互逻辑
  • 物理系统实现真实运动与碰撞
  • 动画系统赋予角色生命力

接下来可探索的方向:

  • UI 系统:显示分数、生命值
  • 音效与特效:增强反馈
  • 敌人 AI:NavMesh 导航与简单行为状态机
  • 场景管理与关卡设计:ProBuilder 快速建模

现在,启动你的 Unity,开始打造属于自己的游戏世界吧!