[方法] Unity 解决类《原神》角色移动方向问题

时间:2024-05-07 08:35:11

第三人称视角类的游戏有很多,比如《原神》、《崩坏:星穹铁道》、《剑星》、《绝地求生》等。这些游戏中,角色的移动方向取决于玩家的输入和相机的方向,例如玩家在键盘上按下D键,则角色会相对于相机方向向右移动,本篇文章就来揭晓这背后的实现方式。

1. 对骨骼动画的设置

首先选中一个骨骼动画,单击 Inspector 面板里的 Animation 选项卡按钮:

我们以行走动画为例,如果我们想让动画中出现的模型偏移来改变角色的实际位置,那么我们就要取消勾选 XZ轴 的 Bake into Pose

如果是跳跃动画,则需要取消勾选 Y轴 的 Bake into Pose

2. 根据位移动画进行模型实际位移

假设目前我们的角色有一个胶囊体(characterController)和一个动画器(animator),并正在播放与位移相关的动画,如下代码实现了动画的运动偏移对模型造成了一个实际的位移:

// [事件] 模型的动画带有位置的偏移
private void OnAnimatorMove()
{
    OnRootMotion(animator.deltaPosition, animator.deltaRotation);
}

private void OnRootMotion(Vector3 deltaPosition, Quaternion deltaRotation)
{
    // 加入重力影响
    deltaPosition.y = gravity * Time.deltaTime;
    // 对玩家进行一个实际的位移
    characterController.Move(deltaPosition);
}

3. 处理模型位移方向

接下来,我们要根据玩家的输入相机的朝向来实现类似于《原神》的角色移动方向的机制,核心代码十分简单,并不需要我们亲自编写旋转算法,拿来即用:

void Update()
{
    // 玩家输入向量:x - 水平输入,y - 垂直输出
    Vector2 moveVector = PlayerInput.input.Player.Move.ReadValue<Vector2>().normalized;
    // 转向过渡
    float rotateSpeed = 5f;

    // -----------核心代码-----------

    // 将玩家的输入组合成一个三维向量
    Vector3 input = new Vector3(moveVector.x, 0, moveVector.y);
    // 拿到相机的朝向
    float y = Camera.main.transform.rotation.eulerAngles.y; 
    // 求得角色的目标移动方向
    Vector3 targetDic = Quaternion.Euler(0, y, 0) * input;
    // 让模型旋转到目标方向
    transform.rotation = Quaternion.Slerp(transform.rotation, 
        Quaternion.LookRotation(targetDic), Time.deltaTime * rotateSpeed);
}