2017-03-09 54 views
1

我有一個懸停坦克,我正在爲它的控制器工作。目標是讓浮標在地面上,但我不想讓它傾斜一兩度。我希望它始終保持水平。如何防止在統一對象中傾斜

我在坦克上使用Rigidbody來控制它與.MovePosition.MoveRotation。您可以在下面看到FixedUpdate函數。我在下面有一個部分來保持思考水平,在​​那裏我檢查坦克是否超過其最大傾斜量。如果是的話,保持在最大。

這使得坦克始終處於非常緊張的狀態。它看起來很快就會彈起來。我認爲這是由於懸停力量,但我不確定。

我怎樣才能保持坦克的水平,同時讓它胡佛?

FixedUdpate

void FixedUpdate() { 
    if (!isServer) { 
     return; 
    } 

    CheckGrounded(); 
    Hoover(); 

    if (_moveForward) { 
     float moveAmount = moveSpeed * Time.deltaTime; 
     _rigidbody.MovePosition(_rigidbody.position + _rigidbody.transform.forward * moveAmount); 
    } 
    if (_moveBackward) { 
     float moveAmount = (-moveSpeed * 0.6f) * Time.deltaTime; 
     _rigidbody.MovePosition(_rigidbody.position + _rigidbody.transform.forward * moveAmount); 
    } 

    if (_turnLeft) { 
     Quaternion rotateAmount = Quaternion.Euler(new Vector3(0f, -angularSpeed, 0f) * Time.deltaTime); 
     _rigidbody.MoveRotation(_rigidbody.rotation * rotateAmount); 
    } 
    if (_turnRight) { 
     Quaternion rotateAmount = Quaternion.Euler(new Vector3(0f, angularSpeed, 0f) * Time.deltaTime); 
     _rigidbody.MoveRotation(_rigidbody.rotation * rotateAmount); 
    } 

    if (_jump && _isGrounded) { 
     _isJumping = true; 
    } 

    if (_isJumping && _jumpTimeLeft > 0) { 
     float moveAmount = jumpSpeed * Time.deltaTime; 
     _rigidbody.MovePosition(_rigidbody.position + _rigidbody.transform.up * moveAmount); 

     _jumpTimeLeft -= Time.deltaTime; 
    } else if (_isJumping) { 
     _isJumping = false; 
     _jumpTimeLeft = jumpTime; 

    } 

    // Keep things level 
    Vector3 rotation = _rigidbody.rotation.eulerAngles; 
    if (rotation.x > maxTilt) { 
     rotation.x = maxTilt; 
    } else if (rotation.x < -maxTilt) { 
     rotation.x = -maxTilt; 
    } 
    if (rotation.y > maxTilt) { 
     rotation.y = maxTilt; 
    } else if (rotation.y < -maxTilt) { 
     rotation.y = -maxTilt; 
    } 
    if (rotation.z > maxTilt) { 
     rotation.z = maxTilt; 
    } else if (rotation.z < -maxTilt) { 
     rotation.z = -maxTilt; 
    } 
    Quaternion q = new Quaternion(); 
    q.eulerAngles = rotation; 
    _rigidbody.rotation = q; 
} 

胡佛

void Hoover() { 
    foreach (Transform hoverPoint in hooverPoints) { 
     Ray ray = new Ray (hoverPoint.position, -hoverPoint.up); 
     RaycastHit hitInfo; 

     if (Physics.Raycast (ray, out hitInfo, hooverHeight)) { 
      float distance = Vector3.Distance (hoverPoint.position, hitInfo.point); 

      if (distance < hooverHeight) { 
       _rigidbody.AddForceAtPosition (hoverPoint.up * hooverForce * (1f - distance/hooverHeight), hoverPoint.position, ForceMode.Force); 
      } 
     } 
    } 
} 

回答

1

我想您看到 '緊張' 的原因是因爲...

所有物理計算和更新在FixedUpdate之後立即發生。 https://docs.unity3d.com/Manual/ExecutionOrder.html

因爲你正在調整在FixedUpdate()傾斜,然後緊接着就是物理引擎運行其計算,這將有時改變傾角值給人一種「抖動」。我有時說的原因是因爲FixedUpdate()可以運行每幀多次(FPS依賴型),這潛在地用於單個幀下面的調用順序:

  1. FixedUpdate() // start frame
  2. PhysicsEngine
  3. FixedUpdate() // end frame

在上面的例子中,將會有沒有抖動,因爲你在物理引擎完成它的事情後重新校正傾斜 - 完全僥倖。然而,當你沒有得到一幀的第二FixedUpdate()通話時,您將擁有:

  1. FixedUpdate() // start frame
  2. PhysicsEngine // end frame

這將導致你的抖動。

所以我的建議是打破你的FixedUpdate()和抵消任何傾斜校正LateUpdate()。原因LateUpdate()始終是渲染幀之前的最後一次更新調用。