简体   繁体   English

夹紧刚体 2D 控制器

[英]Clamp rigidbody2D Controller

I have a class that deals with the control of a ship, and I want to clamp the position on the y axis.我有一个处理船舶控制的类,我想在 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;
}
}

Thank you very much in advance.非常感谢您提前。

Whenever dealing with Rigidbody or Rigidbody2D there are two main rules每当处理RigidbodyRigidbody2D ,有两个主要规则

  1. Do not do things in Update but rather in FixedUpdate which is used for all Physics and Physics2D engine related calculation.不要做的事情Update而是FixedUpdate其用于所有物理和Physics2D引擎相关的计算。

    Moving the object in Update would cause some jitter and braking the Physics reactions like collisions etc.Update移动对象会导致一些抖动并阻止物理反应,如碰撞等。

  2. Do not go directly through the Transform component but use properties and methods of the Rigidbody or Rigidbody2D instead!不要直接通过Transform组件,而是使用RigidbodyRigidbody2D属性和方法!

    Like in your case Rigidbody2D.MovePosition or Rigidbody2D.velocity就像你的情况Rigidbody2D.MovePositionRigidbody2D.velocity

    Again moving the object via the Transform component breaks the Physics再次通过Transform组件移动对象会破坏物理

so your code should be like所以你的代码应该像

// 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);
}

or alternatively you could also simply directly assign this new velocity to the rigidbody或者,您也可以简单地将这个新速度直接分配给刚体

// 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;
}

Typed on smartphone but I hope the idea gets clear在智能手机上打字,但我希望这个想法变得清晰

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM