每当处理Rigidbody
或Rigidbody2D
有两个主要规则
不要在其中做事情Update
而是在FixedUpdate
其中用于所有 Physics 和 Physics2D 引擎相关的计算。
将对象移入Update
会导致一些抖动并制动物理反应,例如碰撞等。
不要直接通过Transform
组件,而是使用Rigidbody
or的属性和方法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;
}
在智能手机上打字,但我希望这个想法很清楚