【问题标题】:Clamp rigidbody2D Controller夹紧刚体2D控制器
【发布时间】:2020-02-11 23:46:21
【问题描述】:

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

非常感谢您。

【问题讨论】:

    标签: c# unity3d position clamp


    【解决方案1】:

    在处理RigidbodyRigidbody2D 时,有两个主要规则

    1. 不要在Update 中做事,而是在FixedUpdate 中做事,它用于所有物理和Physics2D 引擎相关的计算。

      Update 中移动对象会导致一些抖动并阻碍物理反应,如碰撞等。

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

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

    在智能手机上输入,但我希望思路清晰

    【讨论】:

    • 是的,我明白了,只是您的代码有些滞后。从某种意义上说,它在颤抖。
    • 缓慢摇动,但仍然摇动......这既不好也不优化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-29
    相关资源
    最近更新 更多