上一篇我们简单的做了一个玩家不动的情况下,如何控制准心来射击子弹,但是显然正常的游戏需要移动玩家本体,所以本篇我们需要补全这部分玩法所需的功能。
人物移动
在我们之前的篇章里面,讲解了如何通过物理引擎来实现物体的物理仿真移动,那么我们是不是可以通过物理引擎来实现人物的移动呢?
当然可以,在我们做之前,我们先给场景里面添加好一个地面和几面墙,我们都使用Cube来拉长实现,因为Cube自带了Collider组件,可以直接支持物理碰撞,实现我们的人物能站在上面不掉下去。之前那个Wall我们也加长一点:
然后我们再新建一个Cube来作为我们的玩家人物,因为我们的人物是需要受物理引擎改变位置的,所以不要忘记加入RigidBody组件:
我们把方块放在比较高的位置,如果跑起来的话可以看到这个Player会掉下来落到Ground上,但是不会掉下去。
ok,现在我们需要加入一个组件来实现对Player的控制效果,也就是我们使用wasd需要能给这个Player的刚体组件提供一个速度。
有请gpt帮我们快速写一个:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 20f; // 控制速度的变量
private Rigidbody rb; // 刚体组件
void Start()
{
rb = GetComponent<Rigidbody>(); // 获取刚体组件
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal"); // 获取水平方向的输入
float moveVertical = Input.GetAxis("Vertical"); // 获取垂直方向的输入
Vector3 movement = new Vector3(moveHorizontal, 0f, moveVertical); // 创建一个移动向量
rb.AddForce(movement * speed); // 将移动向量乘以速度并添加到刚体上
}
}
值得注意的是,gpt正确的意识到了物理引擎相关的每帧操作需要在FixedUpdate里面而非Update里面,这跟Unity内部各个系统执行的顺序有关,如果你用了错误的Update,那么可能就会出现你这帧设置的物理数据,没有及时的在本帧体现出来,而是延迟到下一帧才体现。
给Player这个方块加上这个PlayerController组件看看效果(注意需要在Scene窗口下观察,因为我们还没实现相机跟着人物的效果):
可以看到虽然确实是受我们的wasd输入影响了,但是感觉很奇怪,是这样几个问题:
- 正常人走路是不可能翻滚的
- 按下wasd会有一个加速的过程,并不是跟真实人走路一样立刻就以一个速度行走了,并且这个速度会随着按住时常加速到越来越快
对于问题1,主要原因是虽然我们只给予了水平方向的力(XZ轴),但是因为来自摩擦力或者碰撞带来的反作用力的计算精度问题,总会出现一些不那么水平的力,所以就会让物体无法保持稳定,就出现了翻滚,我们如果需要保持物体不翻滚,就可以锁定RigidBody组件里面的对应坐标轴:<