Unity Player与水平小对撞机碰撞

时间:2019-01-25 01:46:11

标签: c# unity3d collision mesh-collider

我知道标题不是很解释,但这是我的问题:

我有一个玩家(仅是一个带有刚体,对撞机和移动脚本的立方体),并且我的地板是一个由1乘1的小立方体(带盒对撞机的立方体)组成的地板。

由于某种我不知道的原因,当我的玩家多维数据集掉落并试图与地板水平碰撞时,他只是逐步通过...但是要他像垂直一样,被多维数据集阻塞。任何帮助将不胜感激;)

这里是场景的样子

这是一个立方体对象

此处是玩家对象

这是玩家穿过地板的gif

这是我的c#播放器移动脚本(我知道它很糟糕,但是我希望将其放在此处,以防它与我的问题有关):

void ApplyMovement()
{        

 transform.position += new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

}

如果您需要更多信息来帮助我,请告诉我,我会尽快提供。

3 个答案:

答案 0 :(得分:0)

我重新创建了您最后描述的场景。我将您的“ ApplyMovement”代码放在“更新”中。我基本上可以重现您的结果。

在我看来,问题可能出在播放器上冻结X / Z位置。我认为既然这样做了,您就是在告诉刚体组件,不允许将对象的X / Z位置修改为碰撞分辨率和物理模拟的一部分。当我关闭这两个功能时,我得到的结果(我认为)更接近您的期望。

请注意:您的“ ApplyMovement”代码是锁定帧的,这意味着您的播放器将以不同的速度以不同的帧速率移动。要解决此问题,您需要将Input.GetAxis值乘以Time.deltaTime。

此外,如果您的玩家移动得太快,它仍然能够通过碰撞并导致奇怪的行为,因此请确保将玩家的最大移动速率限制在某个合理的值。

答案 1 :(得分:0)

您应该对角色的Rigidbody施加力,而不要直接操纵transform.position(这将阻止物理引擎解决碰撞)。您还将冻结Rigidbody上的X和Z位置;您不希望这样做,因为它完全阻止Rigidbody处理这些值。

首先在脚本中的某个位置获得对transform.postion += ...的引用,而不是Rigidbody(最好在Awake()方法中进行操作):

private Rigidbody _body;
private void Awake() {
    _body = GetComponent<Rigidbody>();
}

然后确保从输入中构建的矢量被应用于对象的“运动”,而不是对象的位置:

Vector3 inputVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// You can multiply this vector by a float to adjust "speed"

_body.ApplyForce(inputVector, ForceMode.VelocityChange);

最后,您应该阅读不同的ForceMode选项,并确定哪个选项符合您的偏好:https://docs.unity3d.com/ScriptReference/ForceMode.html

别忘了这应该在FixedUpdate()而不是Update()中发生(所有物理操作应在FixedUpdate()中完成)


请注意,您的刚体还有可能仍然移动得太快并互相穿过。即使在使用力和速度时,这也是可能的,因此,如果您遇到这种情况,请调查Collision Detection Modes。 TLDR;它们是性能与准确性之间权衡的设置。

答案 2 :(得分:0)

  1. 的值
    new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"))
    

    与帧速率有关。这意味着帧速率越快,对象移动的速度就越快。这通常不是您想要的。而是使用Time.deltaTime

    // Adjust the speed in the inspector
    public float speedMultiplicator = 1;
    
    //...
    
    new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")) * speedMultiplicator * Time.deltaTime
    

    以获得独立于帧速率的运动。另请参见Input.GetAxis中的示例。

  2. 在处理RigidBody时,切勿直接更改transform.position(和rotation)!

    如果您想使RigidBody跳到某个位置,而不要使用

    rigidBody.position = transform.position + ...;
    

    不过,您想要的是平稳移动,以保持碰撞检测完好无损。因此,您应该改用RigidBody.MovePosition

    rigidBody.MovePosition(transform.position + ...);
    

    您不必对付武力等。

  3. 还向地板对象添加一个RigidBody组件。即使对象没有移动,这也可以改善碰撞检测(以物理引擎为代价)。而且由于对象不应该移动集合

    • isKinematic-> true
    • 使用重力->假

    您还可以设置freeze positionfreeze rotation

  4. 在楼层和播放器对象上均设置Collision Detection-> Continous Dynamic
    这样可以改善碰撞检测,并在帧之间查找碰撞。
    但是请注意,动态检测非常昂贵,因此只有在对象过快时仍然有问题时才使用它。

  5. 在播放器上,您可能还希望使用interpolate

  6. 最后

      

    请注意,连续碰撞检测旨在作为一种安全网,以防万一物体相互之间通过而无法传递物理上准确的碰撞结果,因此您仍可以考虑在TimeManager检查器   如果您遇到快速移动物体的问题,则可以使仿真更加精确。

有关更多信息,请参见RigidBody manualColliders manual