我们可以统一使用 Physics.Simulate 来检测刚体何时发生碰撞吗
Can we detect when a rigid body collides using Physics.Simulate in unity
public void RunSimulation()
{
Physics.autoSimulation = false;
simulatedBodies = FindObjectsOfType<Rigidbody>().Select(rb => new SimulatedBody(rb)).ToArray();
striker.GetComponent<Rigidbody> ().AddForce (new Vector3 (200.0f, 0.0f, 200.0f));
for (int i = 0; i < maxIterations; i++)
{
Physics.Simulate(0.02f);
//GET COLLISIONS HERE
if (simulatedBodies.All(body => body.rigidbody.IsSleeping()))
{
print(i);
break;
}
}
Physics.autoSimulation = true;
}
我正在尝试统一使用 physics.simulate。根据统一文档“模拟包括碰撞检测、刚体和关节集成的所有阶段,以及物理回调的归档(接触、触发器和关节”
我需要了解我的前锋游戏对象在哪个迭代中与其他游戏对象发生碰撞。如果我使用自动模拟,OnCollisionEnter 会起作用。但是,当我使用 Physics.Simulate 它不注册时它不起作用。当我的对象与其他对象发生碰撞时,我做错了什么或如何得到。
Can we detect when a rigid body collides using Physics.Simulate in
unity
是的,可以。
我曾经对此做过一个实验,它成功了,我打开使用过的相同示例场景再次进行测试,它又成功了。这是文档中的声明,也在您的问题中:
Simulation includes all the stages of collision detection, rigidbody
and joints integration, and filing of the physics callbacks
(contact, trigger and joints).
因此,它可以检测碰撞。
If I user auto simulation, OnCollisionEnter works. However it doesn't
work when I use Physics.Simulate it doesn't register.
你不能使用IsSleeping()
来获得碰撞。假设您正确设置了对撞机和刚体,那么 问题是 maxIterations
值 太小 导致模拟未完成且未到达目的地它应该与另一个对象发生碰撞的地方。 如果没有发生碰撞,将不会调用 OnCollisionEnter
。
增加你的 maxIterations
以使其在模拟中移动更远的距离,并且应该调用 OnCollisionEnter
。至于检测你的游戏对象与其他游戏对象发生碰撞的迭代,使用布尔变量作为标志并在 OnCollisionEnter
函数中将其设置为 true
然后在 for
循环中将其设置为 break
当这个布尔变量是 true
.
const int maxIterations = 60;
int collideIteration = 0;
bool collided = false;
public void RunSimulation()
{
//RESET OLD VALUES
collided = false;
collideIteration = 0;
Physics.autoSimulation = false;
Rigidbody rbdy = GetComponent<Rigidbody>();
rbdy.AddForce(new Vector3(200.0f, 0.0f, 200.0f));
for (int i = 0; i < maxIterations; i++)
{
Physics.Simulate(0.02f);
//Check if collided then break out of the loop
if (collided)
{
collideIteration = i;
print(i);
break;
}
}
Physics.autoSimulation = true;
}
public int GetCollideIteration()
{
return collideIteration;
}
void OnCollisionEnter(Collision collision)
{
collided = true;
Debug.Log("Collision: " + collision.collider.name);
}
如果增加 maxIterations
没有解决您的问题,请查看 。它将在 x 秒内进行模拟。 5
秒在下面的代码中使用,唯一改变的是 RunSimulation()
函数。上面的其余代码仍然有效:
public void RunSimulation()
{
//RESET OLD VALUES
collided = false;
collideIteration = 0;
Physics.autoSimulation = false;
Rigidbody rbdy = GetComponent<Rigidbody>();
rbdy.AddForce(new Vector3(200.0f, 0.0f, 200.0f));
//Simulate where it will be in 5 seconds
float timeInSec = 5f;
int i = 0;
while (timeInSec >= Time.fixedDeltaTime)
{
timeInSec -= Time.fixedDeltaTime;
Physics.Simulate(Time.fixedDeltaTime);
//Check if collided then break out of the loop
if (collided)
{
collideIteration = i;
print(i);
break;
}
i++;
}
Physics.autoSimulation = true;
}
public void RunSimulation()
{
Physics.autoSimulation = false;
simulatedBodies = FindObjectsOfType<Rigidbody>().Select(rb => new SimulatedBody(rb)).ToArray();
striker.GetComponent<Rigidbody> ().AddForce (new Vector3 (200.0f, 0.0f, 200.0f));
for (int i = 0; i < maxIterations; i++)
{
Physics.Simulate(0.02f);
//GET COLLISIONS HERE
if (simulatedBodies.All(body => body.rigidbody.IsSleeping()))
{
print(i);
break;
}
}
Physics.autoSimulation = true;
}
我正在尝试统一使用 physics.simulate。根据统一文档“模拟包括碰撞检测、刚体和关节集成的所有阶段,以及物理回调的归档(接触、触发器和关节” 我需要了解我的前锋游戏对象在哪个迭代中与其他游戏对象发生碰撞。如果我使用自动模拟,OnCollisionEnter 会起作用。但是,当我使用 Physics.Simulate 它不注册时它不起作用。当我的对象与其他对象发生碰撞时,我做错了什么或如何得到。
Can we detect when a rigid body collides using Physics.Simulate in unity
是的,可以。
我曾经对此做过一个实验,它成功了,我打开使用过的相同示例场景再次进行测试,它又成功了。这是文档中的声明,也在您的问题中:
Simulation includes all the stages of collision detection, rigidbody and joints integration, and filing of the physics callbacks (contact, trigger and joints).
因此,它可以检测碰撞。
If I user auto simulation, OnCollisionEnter works. However it doesn't work when I use Physics.Simulate it doesn't register.
你不能使用IsSleeping()
来获得碰撞。假设您正确设置了对撞机和刚体,那么 问题是 maxIterations
值 太小 导致模拟未完成且未到达目的地它应该与另一个对象发生碰撞的地方。 如果没有发生碰撞,将不会调用 OnCollisionEnter
。
增加你的 maxIterations
以使其在模拟中移动更远的距离,并且应该调用 OnCollisionEnter
。至于检测你的游戏对象与其他游戏对象发生碰撞的迭代,使用布尔变量作为标志并在 OnCollisionEnter
函数中将其设置为 true
然后在 for
循环中将其设置为 break
当这个布尔变量是 true
.
const int maxIterations = 60;
int collideIteration = 0;
bool collided = false;
public void RunSimulation()
{
//RESET OLD VALUES
collided = false;
collideIteration = 0;
Physics.autoSimulation = false;
Rigidbody rbdy = GetComponent<Rigidbody>();
rbdy.AddForce(new Vector3(200.0f, 0.0f, 200.0f));
for (int i = 0; i < maxIterations; i++)
{
Physics.Simulate(0.02f);
//Check if collided then break out of the loop
if (collided)
{
collideIteration = i;
print(i);
break;
}
}
Physics.autoSimulation = true;
}
public int GetCollideIteration()
{
return collideIteration;
}
void OnCollisionEnter(Collision collision)
{
collided = true;
Debug.Log("Collision: " + collision.collider.name);
}
如果增加 maxIterations
没有解决您的问题,请查看 5
秒在下面的代码中使用,唯一改变的是 RunSimulation()
函数。上面的其余代码仍然有效:
public void RunSimulation()
{
//RESET OLD VALUES
collided = false;
collideIteration = 0;
Physics.autoSimulation = false;
Rigidbody rbdy = GetComponent<Rigidbody>();
rbdy.AddForce(new Vector3(200.0f, 0.0f, 200.0f));
//Simulate where it will be in 5 seconds
float timeInSec = 5f;
int i = 0;
while (timeInSec >= Time.fixedDeltaTime)
{
timeInSec -= Time.fixedDeltaTime;
Physics.Simulate(Time.fixedDeltaTime);
//Check if collided then break out of the loop
if (collided)
{
collideIteration = i;
print(i);
break;
}
i++;
}
Physics.autoSimulation = true;
}