【问题标题】:Predict the position of a Rigidbody Object in x second在 x 秒内预测刚体对象的位置
【发布时间】:2017-08-03 12:55:51
【问题描述】:

假设您有一个移动的Rigidbody 对象。通过Rigidbody.AddForceRigidbody.velocity 将力添加到此对象。该物体可以滚动撞击另一个物体并改变方向。

我知道Extrapolation,但在这种情况下,几乎不可能使用某些公式在 x 秒内获得对象的位置,因为对象可以撞击另一个对象并改变速度/过程中的方向。

Unity 2017 引入了Physics.autoSimulationPhysics.Simulate 来解决这个问题。对于二维物理,即Physics2D.autoSimulationPhysics2D.Simulate。我所做的只是首先将Physics.autoSimulation 设置为false,然后调用Physics.Simulate 函数。


在我的示例中,我想知道Rigidbody 在对其施加力后在4 秒内的位置,它似乎在像1 这样的小几秒内工作正常。问题是,当我将较大的数字(如 5 及以上)传递给 Simulate 函数时,预测的位置准确。差远了

为什么会发生这种情况,我该如何解决?这个问题在 Android 设备上更为严重。

我当前的 Unity 版本是 Unity 2017.2.0b5

以下是我正在使用的示例代码。 guide GameObject 仅用于显示/显示预测位置的位置。

public GameObject bulletPrefab;
public float forceSpeed = 50;

public GameObject guide;

// Use this for initialization
IEnumerator Start()
{
    //Disable Physics AutoSimulation
    Physics.autoSimulation = false;

    //Wait for game to start in the editor before moving on(NOT NECESSARY)
    yield return new WaitForSeconds(1);

    //Instantiate Bullet
    GameObject obj = Instantiate(bulletPrefab);

    Rigidbody bulletRigidbody = obj.GetComponent<Rigidbody>();

    //Calcuate force speed. (Shoot towards the x + axis)
    Vector3 tempForce = bulletRigidbody.transform.right;
    tempForce.y += 0.4f;
    Vector3 force = tempForce * forceSpeed;

    //Addforce to the Bullet
    bulletRigidbody.AddForce(force, ForceMode.Impulse);

    //yield break;
    //Predict where the Rigidbody will be in 4 seconds
    Vector3 futurePos = predictRigidBodyPosInTime(bulletRigidbody, 4f);//1.3f
    //Show us where that would be
    guide.transform.position = futurePos;
}

Vector3 predictRigidBodyPosInTime(Rigidbody sourceRigidbody, float timeInSec)
{
    //Get current Position
    Vector3 defaultPos = sourceRigidbody.position;

    Debug.Log("Predicting Future Pos from::: x " + defaultPos.x + " y:"
        + defaultPos.y + " z:" + defaultPos.z);

    //Simulate where it will be in x seconds
    Physics.Simulate(timeInSec);

    //Get future position
    Vector3 futurePos = sourceRigidbody.position;

    Debug.Log("DONE Predicting Future Pos::: x " + futurePos.x + " y:"
        + futurePos.y + " z:" + futurePos.z);

    //Re-enable Physics AutoSimulation and Reset position
    Physics.autoSimulation = true;
    sourceRigidbody.velocity = Vector3.zero;
    sourceRigidbody.useGravity = false;
    sourceRigidbody.position = defaultPos;

    return futurePos;
}

【问题讨论】:

    标签: c# unity3d rigid-bodies


    【解决方案1】:

    您甚至很幸运1 的值完全起作用。您不应将任何高于 0.03 的值传递给 Physics.SimulatePhysics2D.Simulate 函数。

    当值大于0.03时,你必须把它分成几块,然后在循环中使用Simulate函数。减少 x 时间,同时检查它是否仍然大于或等于 Time.fixedDeltaTime 应该这样做。

    替换

    Physics.Simulate(timeInSec);
    

    while (timeInSec >= Time.fixedDeltaTime)
    {
        timeInSec -= Time.fixedDeltaTime;
        Physics.Simulate(Time.fixedDeltaTime);
    }
    

    您的新完整 predictRigidBodyPosInTime 函数应如下所示:

    Vector3 predictRigidBodyPosInTime(Rigidbody sourceRigidbody, float timeInSec)
    {
        //Get current Position
        Vector3 defaultPos = sourceRigidbody.position;
    
        Debug.Log("Predicting Future Pos from::: x " + defaultPos.x + " y:"
            + defaultPos.y + " z:" + defaultPos.z);
    
        //Simulate where it will be in x seconds
        while (timeInSec >= Time.fixedDeltaTime)
        {
            timeInSec -= Time.fixedDeltaTime;
            Physics.Simulate(Time.fixedDeltaTime);
        }
    
        //Get future position
        Vector3 futurePos = sourceRigidbody.position;
    
        Debug.Log("DONE Predicting Future Pos::: x " + futurePos.x + " y:"
            + futurePos.y + " z:" + futurePos.z);
    
        //Re-enable Physics AutoSimulation and Reset position
        Physics.autoSimulation = true;
        sourceRigidbody.velocity = Vector3.zero;
        sourceRigidbody.useGravity = false;
        sourceRigidbody.position = defaultPos;
    
        return futurePos;
    }
    

    【讨论】:

      【解决方案2】:

      我知道这是一个迟到的回应,但如果有人想知道如何解决这个问题。因此,我阅读了有关rigidbody.velocity 的文档,如果将其添加到刚体的位置,您将在1 秒内获得刚体的位置,因此,如果您获得速度,请将其乘以您希望看到的秒数未来,然后将其添加到刚体的位置,您将在 x 秒内得到刚体的位置,像这样

      {
      Vector3 PredictionPos(Rigidbody _TargetRb, float _predictiontime){
      
      //get the rigidbodies velocity
      Vector3 _targvelocity = _TargetRB.velocity;
      //multiply it by the amount of seconds you want to see into the future
      _targvelocity *= _predictiontime;
      //add it to the rigidbodies position
      _targvelocity += _TargetRB.position;
      //Return the position of where the target will be in the amount of seconds you want to see into the future
      Return _targvelocity;
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-12
        • 2022-10-18
        • 1970-01-01
        • 2019-03-13
        • 2017-05-13
        • 1970-01-01
        相关资源
        最近更新 更多