簡體   English   中英

如何在unity3d中平穩地上下移動剛體對象

[英]How to move rigidbody object up or down smoothly in unity3d

我已經開始了一個項目,並在播放器上附加了剛體以對其施加一些力。因此,當我運行項目時,在FixedUpdate()函數中,我會向播放器施加力以使其向前移動。或右箭頭執行“傾斜”表示旋轉翅膀。 但是現在我想通過按Uparrow或Downarrow平穩地上下移動播放器,當我同時按下Uparrow和Downarrow時,這一定會對播放器產生影響。 這是我的代碼。請幫助我。 :(

void FixedUpdate ()
{
  rb.AddForce(transform.forward *1000f);
  float movedir = Input.GetAxis ("Horizontal");

  Vector3 movement = new Vector3 (movedir, 0.0f, 0.0f);
  rb.velocity = movement * movingspeed;
  rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -3f);//perform tilt


 if (Input.GetKeyDown (KeyCode.UpArrow)) 
      { 
       //code for smoothly move up from current position to = current position + 2f 
      }

  if (Input.GetKeyDown (KeyCode.DownArrow)) 
      { 
        //code for smoothly move down from current position to = current position - 2f 
      }


}

您的問題還不清楚。 smoothly移動可能意味着很多事情。

通常,您應該使用RigidBody.MovePositionRigidbody.MoveRotation來設置Rigidbody的變換,而不是rb.rotationrb.position來獲得“平滑”運動:

使用Rigidbody.MovePosition來移動Rigidbody,遵守Rigidbody的插值設置。

如果在Rigidbody上啟用了Rigidbody插值,則調用Rigidbody.MovePosition會導致所渲染的任何中間幀中兩個位置之間的平滑過渡。 如果要在每個FixedUpdate中連續移動剛體,則應使用此方法。

如果要將剛體從一個位置傳送到另一個位置,而不渲染任何中間位置,請設置Rigidbody.position。

如您所見,根據使用Rigidbody.MovePosition的設置,可能已經導致“平滑”運動。

rb.MovePosition(transform.position + Vector3.up * 2.0f);

另外,您也使用Input.GetKeyDown因此它像觸發器一樣工作……它不會像Input.GetKey那樣連續Input.GetKey

如果要在按住鍵的同時連續移動,請使用例如

// set e.g. in the inspector
public float verticalMoveSpeed;

// ...

if (Input.GetKey(KeyCode.UpArrow)) 
{ 
    rb.MovePosition(transform.position + Vector3.up * verticalMoveSpeed * Time.deltaTime);
}

if (Input.GetKey(KeyCode.DownArrow)) 
{ 
    rb.MovePosition(transform.position - Vector3.up * verticalMoveSpeed * Time.deltaTime);
}

如果您只想使用GetKeyDown觸發移動,也可以執行例如

// set e.g. in the inspector
public float verticalMoveSpeed;

// ...

if (Input.GetKeyDown(KeyCode.UpArrow)) 
{ 
    StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed));
} 
else if (Input.GetKeyDown(KeyCode.DownArrow)) 
{ 
    StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed));
}

// ...

private IEnumerator MoveVertical(float distance, float speed)
{
    var originalY = transform.position.y;
    var targetY = originalY + distance;

    var currentY = originalY; 
    do
    {     
        rb.MovePosition(new Vector 3(transform.position.x, currentY, transform.positiom.z);

        // Update currentY to the next Y position
        currentY = Mathf.Clamp(currentY + speed * Time.deltaTime, originalY, targetY);
        yield return null;
    }
    while(currentY < originalY);

    // make sure you didn't move to much on Y
    rb.MovePosition(new Vector3(transform.position.x, targetY, transform.position,z));
}

有兩種方法可以防止並發例程:

  1. 使用一個標志。 這也可以防止例程蜂鳴被打斷/兩次調用/並發

     privtae bool isMovingVertical; // ... if (Input.GetKeyDown(KeyCode.UpArrow) && !isMovingVertical ) { StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed)); } else if (Input.GetKeyDown(KeyCode.DownArrow) && !isMovingVertical ) { StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed)); } // ... private IEnumerator MoveVertical(float distance, float speed) { isMovingVertical = true; // ... isMovingVertical = false; } 
  2. 使用StopAllCoroutines中斷正在運行的例程(注意,這可能會導致一個方向上的“無限”移動-至少在沒有通過附加檢查阻止它的情況下)

     if (Input.GetKeyDown(KeyCode.UpArrow)) { StopAllCoroutines(); StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed)); } if (Input.GetKeyDown(KeyCode.DownArrow)) { StopAllCoroutines(); StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed)); } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM