我有一个问题,大约两天没能解决。
我使用 mixamo 中的角色为(W、S、A、D)键制作了一个简单的第三人称角色控制器,问题是当我停止按 W 键时,角色会继续向前行走半秒,更像是如果它在冰上滑动的话,这是否有意义。
有人熟悉这个问题并知道如何解决吗?
PlayerController.cs
public class PlayerController : MonoBehaviour
{
[SerializeField] float moveSpeed = 5f;
[SerializeField] float rotationSpeed = 1000f;
Quaternion targetRotation;
CameraController cameraController;
private void Awake() {
cameraController = Camera.main.GetComponent<CameraController>();
}
private void Update() {
float horizontal = Input.GetAxis("Horizontal");
float vartical = Input.GetAxis("Vertical");
float moveAmount = Mathf.Clamp01(Mathf.Abs(horizontal) + Mathf.Abs(vartical));
var moveInput = new Vector3(horizontal, 0, vartical).normalized;
var moveDirection = cameraController.PlanerRotation * moveInput;
if (moveAmount > 0) {
transform.position += moveSpeed * Time.deltaTime * moveDirection;
targetRotation = Quaternion.LookRotation(moveDirection);
}
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation,
rotationSpeed * Time.deltaTime);
}
}
如果相关的话,这是相机控制器
public class CameraController : MonoBehaviour
{
[SerializeField] Transform target;
[SerializeField] float sensitivityX;
[SerializeField] float sensitivityY;
[SerializeField] float distance = 3;
[SerializeField] float minVarticalClamp = -10;
[SerializeField] float maxVarticalClamp = 45;
[SerializeField] Vector2 framingOffset;
[SerializeField] bool invertX;
float rotationX;
float rotationY;
float invertXVal;
private void Start() {
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
private void Update() {
invertXVal = (invertX) ? -1 : 1;
rotationX += Input.GetAxis("Mouse Y") * invertXVal * sensitivityX;
rotationX = Mathf.Clamp(rotationX, minVarticalClamp, maxVarticalClamp);
rotationY += Input.GetAxis("Mouse X") * sensitivityY;
var targetRotation = Quaternion.Euler(rotationX, rotationY, 0);
var focusPosition = target.position + new Vector3(framingOffset.x, framingOffset.y);
transform.position = focusPosition - targetRotation * new Vector3(0, 0, distance);
transform.rotation = targetRotation;
}
public Quaternion PlanerRotation => Quaternion.Euler(0, rotationY, 0);
}
出现您的问题是因为 此函数已平滑。
Input.GetAxis()
这意味着它模拟操纵杆的工作原理;当您释放按钮时,它会平滑地过渡到零,而不是立即发生。
如果您不想要这种行为,您可以使用 此函数代替。
Input.GetAxisRaw()
这将表现得像一个按钮并且不应用平滑。
值得注意的是,平滑可能正是您想要的,但您可能只是处理得不好。
类似这样的事情
private void Update() {
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
float nonNormalInput = new Vector3(horizontal, 0, vertical);
var moveInput = nonNormalInput.normalized;
var moveDirection = cameraController.PlanerRotation * moveInput;
if (nonNormalInput.magnitude > 0) {
transform.position += moveSpeed * Time.deltaTime * moveDirection * nonNormalInput.magnitude;
targetRotation = Quaternion.LookRotation(moveDirection);
}
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation,
rotationSpeed * Time.deltaTime);
}
会给你带来平滑的好处,或者你可以使用
Input.GetAxisRaw()
完全忽略它。我通常用Input.GetAxisRaw()
。