Хомут контролер Hardbody2D - PullRequest
       61

Хомут контролер Hardbody2D

0 голосов
/ 11 февраля 2020

У меня есть класс, который управляет кораблем, и я хочу зафиксировать позицию на оси Y.

 public class ControlledRigidbody2D : MonoBehaviour
{
public float verticalInputAcceleration = 1;
public float horizontalInputAcceleration = 20;
public float maxSpeed = 10;
public float velocityDrag = 1;
private Vector3 velocity;
private void Update()
{
    Vector3 acceleration = Input.GetAxis("Vertical") * verticalInputAcceleration * transform.up;
    velocity.y += acceleration.y * Time.deltaTime;
    Vector3 accelerationRight = Input.GetAxis("Horizontal") * horizontalInputAcceleration * transform.right;
    velocity.x += accelerationRight.x * Time.deltaTime; ;
    velocity = velocity * (1 - Time.deltaTime * velocityDrag);
    velocity = Vector3.ClampMagnitude(velocity, maxSpeed);
    transform.position += velocity * Time.deltaTime;
}
}

Заранее большое спасибо.

1 Ответ

2 голосов
/ 11 февраля 2020

Всякий раз, когда речь идет о Rigidbody или Rigidbody2D, существуют два основных правила

  1. Не делайте вещи в Update, а скорее в FixedUpdate который используется для всех расчетов движка Physics и Physics2D.

    Перемещение объекта в Update приведет к некоторому дрожанию и торможению физических реакций, таких как столкновения и т. Д. c.

  2. Не go непосредственно через Transform, но используйте вместо этого свойства и методы Rigidbody или Rigidbody2D!

    Как и в вашем случае Rigidbody2D.MovePosition или Rigidbody2D.velocity

    Повторное перемещение объекта с помощью компонента Transform нарушает физику

, поэтому ваш код должен быть похож на

// already reference the component via the Inspector
[SerializeField] Rigidbody2D rb;

Vector3 acceleration;
Vector3 accelerationRight;

privtae void Awake()
{
    if(!rb) rb = GetComponent<Rigidbody2D>();
}

// Get user input within Update
private void Update()
{
    acceleration = Input.GetAxis("Vertical") * verticalInputAcceleration * transform.up;
    accelerationRight = Input.GetAxis("Horizontal") * horizontalInputAcceleration * transform.right;
}

// update the Rigidbody in FixedUpdate
private void FixedUpdate()
{
    velocity = rb.velocity;

    // do these here so Time.deltaTime uses the correct value
    velocity += acceleration * Time.deltaTime;
    velocity += accelerationRight * Time.deltaTime;
    velocity = velocity * (1 - Time.deltaTime * velocityDrag);
    velocity = Vector3.ClampMagnitude(velocity, maxSpeed);

    // Problem: MovePosition expects a value in global world space
    // so if your velocity is in local space 
    // - which seems to be the case  - you will have to convert 
    // it into a global position first
    var newPosition = rb.position + transform.TransformDirection(velocity  * Time.deltaTime);
    rb.MovePosition(newPosition);
}

, или же вы можете просто назначить эту новую скорость жесткому телу

// update the Rigidbody in FixedUpdate
private void FixedUpdate()
{
    velocity = rb.velocity;

    // do these here so Time.deltaTime uses the correct value
    velocity += acceleration * Time.deltaTime;
    velocity += accelerationRight * Time.deltaTime;
    velocity = velocity * (1 - Time.deltaTime * velocityDrag);
    velocity = Vector3.ClampMagnitude(velocity, maxSpeed);

    rb.velocity = velocity;
}

Набрано на смартфоне, но я надеюсь, что идея проясняется

...