在 x 秒内预测刚体对象的位置 [英] Predict the position of a Rigidbody Object in x second

查看:29
本文介绍了在 x 秒内预测刚体对象的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个移动的 Rigidbody 对象.力通过Rigidbody.AddForceRigidbody.velocity 添加到这个对象.Object 可以滚动击中另一个 Object 并改变方向.

Let's say that you have a Rigidbody Object that moves. Force is added to this Object via Rigidbody.AddForce or Rigidbody.velocity. The Object can roll hit another Object and change direction.

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

I know about Extrapolation but in this case, it's nearly impossible to use some formula to obtain the position of the object in x seconds, since the Object can hit another object and change speed/direction in the process.

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

Unity 2017 introduced Physics.autoSimulation and Physics.Simulate to solve this problem. For 2D physics, that is Physics2D.autoSimulation and Physics2D.Simulate. All I did was first set Physics.autoSimulation to false then call the Physics.Simulate function.

在我的示例中,我想知道 Rigidbody 在向其添加力后 4 秒内的位置,它似乎可以像 1.问题是,当我向 Simulate 函数传递更大的数字(如 5 及以上)时,预测位置准确.好远啊

In my example, I wanted to know where a Rigidbody would be in 4 seconds after adding force to it, it seems to work fine for tiny seconds like 1. The problem is that when I pass in bigger numbers like 5 and above, to the Simulate function, the predicted position is not accurate. It's way way off.

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

Why is this happening and how can I fix it? This problem is worse on Android devices.

我当前的 Unity 版本是 Unity 2017.2.0b5.

My current Unity version is Unity 2017.2.0b5.

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

Below is the sample code I am using. The guide GameObject is simply used to display/show where that predicted position is.

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

推荐答案

您甚至很幸运,1 的值确实有效.您不应将任何高于 0.03 的值传递给 Physics.SimulatePhysics2D.Simulate 函数.

You are even lucky that the value of 1 worked at-all. You shouldn't pass any value above 0.03 to the Physics.Simulate or Physics2D.Simulate function.

当该值高于 0.03 时,您必须将其拆分,然后在循环中使用 Simulate 函数.减少 x 时间,同时检查它是否仍然大于或等于 Time.fixedDeltaTime 应该这样做.

When the value is above 0.03, you have to it into pieces then use the Simulate function in a loop. Decrementing the x time while checking if it is still more or equals to Time.fixedDeltaTime should do it.

替换

Physics.Simulate(timeInSec);

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

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

Your new complete predictRigidBodyPosInTime function should look something like this:

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

这篇关于在 x 秒内预测刚体对象的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆