[英]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每当处理
Rigidbody
或Rigidbody2D
,有两个主要规则
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
移动对象会导致一些抖动并阻止物理反应,如碰撞等。
Do not go directly through the Transform
component but use properties and methods of the Rigidbody
or Rigidbody2D
instead!不要直接通过
Transform
组件,而是使用Rigidbody
或Rigidbody2D
属性和方法!
Like in your case Rigidbody2D.MovePosition
or Rigidbody2D.velocity
就像你的情况
Rigidbody2D.MovePosition
或Rigidbody2D.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.