首页 > 解决方案 > 只限制玩家输入而不限制外力(Rigidbody 3D)

问题描述

我一直在尝试正确限制我的 3D fps 控制器上的移动,到目前为止,我一直在使用基本夹紧来限制 X 和 Z 轴上的速度。这样做的问题是任何外力都不会导致玩家超过其预定义的最大速度,这意味着像爆炸这样的外力基本上不会像爆炸那样移动玩家。我想让它工作的想法是只在玩家低于某个最大速度时才允许额外的运动输入,但到目前为止我还无法让它在代码中工作。我对使用向量在 3D 空间中工作还很陌生,所以我很不知道该怎么做。我尝试的实现一直有效,直到玩家在移动时转过头,此时移动不会受到限制。这是我尝试过的代码:

xInput = Input.GetAxisRaw("Horizontal");
yInput = Input.GetAxisRaw("Vertical");
    
if (xInput > 0 && transform.InverseTransformDirection(rb.velocity).x > inputMaximumSpeed) xInput = 0;
if (xInput < 0 && transform.InverseTransformDirection(rb.velocity).x > -inputMaximumSpeed) xInput = 0;
if (yInput > 0 && transform.InverseTransformDirection(rb.velocity).z > inputMaximumSpeed) yInput = 0;
if (yInput < 0 && transform.InverseTransformDirection(rb.velocity).z > -inputMaximumSpeed) yInput = 0;
    
//Apply Movement
moveDirection = (xInput * transform.right + yInput * transform.forward).normalized;
rb.AddForce(moveDirection * groundAccSpeed);

不太确定该怎么做才能解决这个问题,因为我几乎没有发现其他人如何让它发挥作用的例子。谢谢你的帮助!

标签: c#unity3d

解决方案


对于负输入部分不应该是例如

//  |
//  v
... < -inputMaximumSpeed

因为您只想在速度太小且输入为负的情况下进行钳位。

我认为另一个问题是:你总是normalize输入。因此,即使输入非常小(或为零),您也可以将其放大到. 您可能宁愿只在幅度大于 时才进行归一化。11

我也建议宁愿使用AddRelativeForce

xInput = Input.GetAxisRaw("Horizontal");
yInput = Input.GetAxisRaw("Vertical");

// Rather store this only once
var relativeVelocity = transform.InverseTransformDirection(rb.velocity);

if (xInput > 0 && relativeVelocity.x > inputMaximumSpeed) xInput = 0;
// rather use else if since the conditions are exclusive
else if (xInput < 0 && relativeVelocity.x < -inputMaximumSpeed) xInput = 0;

if (yInput > 0 && relativeVelocity.z > inputMaximumSpeed) yInput = 0;
else if (yInput < 0 && relativeVelocity.z < -inputMaximumSpeed) yInput = 0;
    
// create a relative vector
moveDirection = new Vector3 (xInput, 0, yInput);
// Normalize only if magnitude exceeds 1
if(moveDirection.sqrMagnitude > 1f) moveDirection.Normalize();
// add the force relative
rb.AddRelativeForce(moveDirection * groundAccSpeed);

推荐阅读