Как плавно перемещать объект твердого тела вверх или вниз в unity3d - PullRequest
0 голосов
/ 21 января 2019

Я запустил проект и прикрепил жесткое тело к своему плееру, чтобы применить к нему некоторую силу. Поэтому, когда я запускаю свой проект, тогда в функции FixedUpdate() я прикладываю силу к игроку, чтобы переместить его в прямом направлении.Я нажал левую или правую стрелку, чтобы выполнить «наклон», значит повернуть крылья.Но теперь я хочу плавно перемещать игрока вверх или вниз, нажимая «Вверх» или «Вниз», и когда я нажимаю «Вверх» или «Вниз», это должно повлиять на игрока.Вот мой код. Пожалуйста, помогите мне.: (

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 
      }


}

1 Ответ

0 голосов
/ 21 января 2019

Ваш вопрос не совсем понятен.Перемещение smoothly может означать много вещей.

В общем случае вы должны использовать RigidBody.MovePosition и Rigidbody.MoveRotation , чтобы установить преобразования Rigidbody вместоrb.rotation и rb.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

Если вы хотите непрерывно двигаться, пока нажата клавиша, используйте, например,

// 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));
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...