我们可以使用Physics检测刚体碰撞的时间。统一模拟

时间:2018-06-05 06:33:05

标签: c# unity3d game-physics

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。根据统一文献&#34; 模拟包括碰撞检测的所有阶段,刚体和关节的整合,以及物理回调的归档(接触,触发和关节&#34; 我需要得到我的前锋gameobject与其他游戏对象碰撞的迭代次数。如果我用户自动模拟,OnCollisionEnter工作。但是当我使用Physics时它不起作用。模拟它没有注册。我做错了什么或当我的物体与其他物体碰撞时如何得到。

1 个答案:

答案 0 :(得分:1)

  

我们可以使用Physics.Simulate来检测刚体碰撞的时间   统一

是的,它可以。

我曾经对此进行了一次实验并且它有效,我打开了相同的样本场景并再次进行了测试,它再次起作用。以下是文档中的声明,该声明也在您的问题中:

  

模拟包括碰撞检测的所有阶段,刚体   和关节集成,以及物理回调的归档   (接触,触发和关节)。

因此,它可以检测到碰撞。

  

如果我使用自动模拟,OnCollisionEnter可以正常工作。然而,它并没有   当我使用Physics时,我会工作。模拟它没有注册。

您无法使用IsSleeping()进行碰撞。假设您已正确设置了对撞机和Rigidbody,那么问题是maxIterations太小导致模拟未完成且未到达应该到达的目标位置与另一个对象发生碰撞。如果未完成此碰撞,则不会调用OnCollisionEnter

增加maxIterations以在模拟中为其提供更多距离移动,并应调用OnCollisionEnter。至于检测GameObject与其他GameObject发生碰撞的迭代,使用布尔变量作为标志,并将其设置为true函数中的OnCollisionEnter,然后break循环中的for当这个布尔变量是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无法解决您的问题,请查看time based simulations。它将在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;
}