预测刚体对象在x秒内的位置 [英] Predict the position of a Rigidbody Object in x second
问题描述
假设您有一个移动的Rigidbody
对象.力通过Rigidbody.AddForce
或Rigidbody.velocity
施加到该对象.该对象可以滚动碰到另一个对象并改变方向.
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.
我了解外推,但是在这种情况下,几乎不可能使用某些公式来在 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.autoSimulation
和 Physics.Simulate
解决此问题.对于2D物理,即 Physics2D.autoSimulation
和 Physics2D.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.
在我的示例中,我想知道在加力后4
秒内Rigidbody
的位置,它似乎可以像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.Simulate
或Physics2D.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屋!