2017-03-09 13 views
1

ホバリングタンクがあり、コントローラ用に作業しています。目標はフロートを地面の上に置くことですが、私はそれを1度または2度以上傾斜させたくありません。私はそれが基本的にすべての時間のレベルを維持したい。ユニティオブジェクトの傾きを防ぐ方法

私は.MovePosition.MoveRotationでそれを制御するためにタンクにRigidbodyを使用しています。下記のFixedUpdate機能を見ることができます。私は、タンクがそのmaxTiltの量を過ぎてきているかどうかをチェックする、レベルを維持するために以下のセクションを持っています。そうであれば、最大でそれを保つ。

これは、タンクを常に非常にジッタリにします。それはすぐに上下にバウンスしているようです。私はそのホバリング力のためだと思うが、私は確信していない。

タンクレベルをフープにしておくにはどうしたらいいですか?

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の直後に計算と更新が行われます。あなたが、その後すぐに計算を実行している物理エンジンが続いているFixedUpdate()で傾きを調整しているので https://docs.unity3d.com/Manual/ExecutionOrder.html

これはは時々は「ジッタ」を与えてチルト値を変更します。

  1. FixedUpdate() // start frame
  2. PhysicsEngine
  3. FixedUpdate() // end frame
FixedUpdate()が潜在的に単一のフレームのための次の呼び出し順序を意味し、フレームごとに複数回(FPS依存)を実行することができますので、私は時々言う理由があります

上記のケースでは、物理エンジンがその結果を完了した後に、フルークを使って傾きを再調整するので、ジッタなしがあります。あなたは、フレーム上の第二FixedUpdate()呼び出しを得ることはありませんただしとき、あなたが持っているでしょう:あなたのジッタになります

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

を。

私はあなたのFixedUpdate()を分解し、傾き補正をLateUpdate()にオフセットすることを提案します。 Becchase LateUpdate()は、常にフレームのレンダリング前の最後の更新呼び出しです。

関連する問題