2017-03-09 1 views
1

호버 탱크가 있는데 컨트롤러를 사용하고 있습니다. 목표는 부유물을 땅 위에 올려 놓는 것입니다. 그러나 나는 그것을 한 두 정도 더 기울이기를 원하지 않습니다. 기본적으로 항상 평평하게 유지하고 싶습니다.유니티 오브젝트에서 기울어 짐을 방지하는 방법

저는 .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()으로 상쇄하는 것입니다. Beclase LateUpdate()은 프레임을 렌더링하기 전에 항상 마지막 업데이트 호출입니다.