Menu
CoddyTech

朝视线方向移动

本课属于 Coddy Unity 学习旅程的“打造真正的游戏”单元。第 42 课,共 60 课。

当摄像机从某个角度看向玩家时,方向键应该按照屏幕上显示的方向移动玩家:按上键时,玩家远离摄像机;按右键时,玩家向摄像机的右侧移动。只有当摄像机沿着 +z 方向观察时,世界坐标轴才会产生这样的效果。因此,要根据摄像机自身的方向来构建移动方向,使用 cam.forward 和 cam.right。

首先需要对这两个方向进行处理。摄像机向下看着玩家时,它的 forward 会指向地面,因此将它的 y 设为 0,只保留沿地面的部分。剩下的向量长度小于 1,摄像机向下倾斜 30 度时约为 0.87,玩家因此会走得更慢,所以要将它归一化。这个行走控制器跟随主摄像机,摄像机向下看着关卡的一个角落:

Transform cam = Camera.main.transform;

Vector3 forward = cam.forward;
forward.y = 0f;
forward.Normalize();
Vector3 right = cam.right;
right.y = 0f;
right.Normalize();

Vector3 move = forward * Input.GetAxisRaw("Vertical") + right * Input.GetAxisRaw("Horizontal");
if (move.magnitude > 1f) move.Normalize();   // 斜向移动不会更快
controller.Move(move * speed * Time.deltaTime);

Camera.main 是标记为 MainCamera 的摄像机。每帧都会读取这两个方向,因此摄像机转动时,控制方向也会保持正确。同时按上键和右键会将两个互相垂直的单位向量相加,得到的向量长度约为 1.41,因此当移动向量长度大于 1 时,会将它归一化。

challenge icon

挑战

中等

让方向键根据旋转的摄像机方向控制玩家行走。

  1. 在 Update() 中复制 cam.forward 和 cam.right,将 y 设为 0,并进行归一化。
  2. dir 等于 forward 乘以原始 "Vertical" 轴的值,再加上 right 乘以 "Horizontal" 轴的值;当其长度大于 1 时进行归一化。
  3. 当 dir != Vector3.zero 时,设置 transform.rotation = Quaternion.LookRotation(dir);。根据 dir * speed 构建 move。

按下 开始:按上方向键会让玩家朝摄像机视线的反方向行走。然后点击 检查。

亲手试试

using UnityEngine;

public class Mover : MonoBehaviour
{
    public float speed = 4f;
    public float gravity = -15f;
    public Transform cam;

    CharacterController controller;
    float verticalSpeed;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        if (controller.isGrounded && verticalSpeed < 0f)
        {
            verticalSpeed = -2f;
        }
        verticalSpeed += gravity * Time.deltaTime;

        // 现在沿世界坐标轴移动:让它相对于 cam 移动,并朝向移动方向
        Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
        move.y = verticalSpeed;
        controller.Move(move * Time.deltaTime);
    }
}

打造真正的游戏中的所有课

自己练习: Unity 在线编辑器