0

我有一个处理船舶控制的课程,我想在 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;
}
}

非常感谢您提前。

4

1 回答 1

1

每当处理RigidbodyRigidbody2D有两个主要规则

  1. 不要在其中做事情Update而是在FixedUpdate其中用于所有 Physics 和 Physics2D 引擎相关的计算。

    将对象移入Update会导致一些抖动并制动物理反应,例如碰撞等。

  2. 不要直接通过Transform组件,而是使用Rigidbodyor的属性和方法Rigidbody2D

    就像你的情况Rigidbody2D.MovePositionRigidbody2D.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;
}

在智能手机上打字,但我希望这个想法很清楚

于 2020-02-11T14:19:44.977 回答