how-to-make-a-video-game-in-unity-movement-e03

Course: 【油管100w+】 Unity 入门视频

《🎮 How to make a Video Game in Unity — MOVEMENT (E03)》

下面是为你整理的 Notion 系统化笔记版,保持系列一致格式(🎮🏛🧭📦📚🧠🧪✅🪄 风格),

结构清晰、可直接复制到 Notion 中记录学习内容。


🎮 视频标题|How to make a Video Game in Unity — MOVEMENT (E03)

👤 主讲人|Brackeys

📅 系列定位|Unity 新手教程系列 Episode 03

🏷 关键词|玩家移动 | Input.GetKey | Rigidbody | Force | Physics Material | if 语句 | 变量 | 帧率独立


🏛 课程目标

实现可控的玩家移动系统(左右+前进),

通过变量、输入检测与物理力结合,掌握 Unity 中最核心的“输入控制”逻辑。


🧭 回顾前集:当前存在的问题

  • 玩家立方体通过 AddForce 向前移动。
  • 但未受约束时容易在物理碰撞中 旋转、跳起、滑动
  • 为了稳定运动,需要优化 Rigidbody 与摩擦。

📦 修复物理滑动问题

1️⃣ 限制旋转(简单方案)

  • 选中 Player → Rigidbody → 勾选 “Freeze Rotation (X)”
  • 这样物体在 X 轴旋转被锁定。
  • 但这会使碰撞后无法自然翻滚。

2️⃣ 改用 Physics Material(推荐方案)

  • Project 面板 → 右键 Create → Physics Material → 命名为 Slippy
  • Dynamic FrictionStatic Friction 都设为 0
  • 拖到 Ground 的 Box Collider 材料槽中。

✅ 结果:地面摩擦为 0,物体滑动更自然;

❌ 仍未限制旋转 → 将由代码控制。


📚 引入变量(Variables)

变量就像「带标签的容器」:

你可以把数据存进去,然后用名字取出来。

数据类型说明示例
int整数(可正可负)int score = 10;
float小数float speed = 3.5f;
string字符串文本string name = "Player";
bool布尔值(真/假)bool isGrounded = true;

🔹 定义变量:

public float forwardForce = 2000f;
  • public:在 Inspector 中可调节。
  • float:带小数的数字类型。
  • forwardForce:变量名。
  • 2000f:默认值(f 表示 float)。

🧠 将变量用于移动力(Force)

替换硬编码常量:

rb.AddForce(0, 0, forwardForce * Time.deltaTime);

→ 现在可以在 Inspector 中自由调整 forwardForce,

实现实时调试游戏手感

🎯 Unity 的强大之处在于所有 public 变量都可实时修改。


🧩 编写 if 语句:输入检测逻辑

if (Input.GetKey("d")) {
    rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0);
}
  • Input.GetKey("d"):检测是否按下 D 键。
  • { } 内的代码只在条件为真时执行。
  • 注意括号与分号语法:
    • 圆括号包条件 ( )
    • 花括号包代码块 { }
    • 每条命令以 ; 结尾。

📦 添加左右移动逻辑

完整代码示例:

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public Rigidbody rb;
    public float forwardForce = 2000f;
    public float sidewaysForce = 500f;

    void FixedUpdate()
    {
        rb.AddForce(0, 0, forwardForce * Time.deltaTime);

        if (Input.GetKey("d"))  // 向右移动
        {
            rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0);
        }

        if (Input.GetKey("a"))  // 向左移动
        {
            rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0);
        }
    }
}

✅ 结果:按 A/D 可控制左右移动,前进力持续向前。


📚 浮点数的 “f” 后缀解释

  • 写作 500f 表示 500.0(浮点类型)。
  • 不加 f 时 Unity 可能会报类型不匹配警告。
  • 整数 int 不需要。

习惯写法:浮点都加 f,保持类型安全。


🧪 输入响应与性能讨论

  • 当前输入写在 FixedUpdate() 中,与物理运算同步。
  • Unity 建议:
    • 简单移动逻辑(AddForce)可放 FixedUpdate。
    • 但“瞬时事件”(如 Jump、攻击)应放 Update() 中检测输入。
  • 理由:
    • Update() 每帧刷新输入状态;
    • FixedUpdate() 可能跳过某些按键触发(低帧率时)。

实践策略:

  • 在 Update() 中检测输入 → 存入布尔变量。
  • 在 FixedUpdate() 中读取这些变量并执行物理操作。

🧠 代码结构优化思路

bool moveLeft, moveRight;

void Update() {
    moveLeft = Input.GetKey("a");
    moveRight = Input.GetKey("d");
}

void FixedUpdate() {
    if (moveLeft)
        rb.AddForce(-sidewaysForce * Time.deltaTime, 0, 0);
    if (moveRight)
        rb.AddForce(sidewaysForce * Time.deltaTime, 0, 0);
}

分离输入检测与物理执行,使游戏响应更精准稳定。


本集总结

模块功能
Rigidbody控制物理属性(力、重力、旋转)
Physics Material调整摩擦与弹性
public 变量可在 Inspector 实时调节
if 语句条件逻辑核心结构
Input.GetKey读取玩家按键
FixedUpdate用于物理计算
Update用于输入检测
deltaTime帧率无关运动

🪄 延伸与练习

  • 增加跳跃功能(Input.GetKeyDown("space") + AddForce(Vector3.up * jumpForce)
  • 引入阻尼或拖拽控制(Rigidbody.drag
  • 使用 Input.GetAxis("Horizontal") 替代多键检测,实现平滑移动。
  • 继续下一集:E04 — Camera Follow & Player Boundaries 🎥