我们可以使用Physics检测何时发生刚体碰撞. [英] Can we detect when a rigid body collides using Physics.Simulate in unity

查看:214
本文介绍了我们可以使用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.根据统一文档,"模拟包括碰撞检测,刚体和关节集成以及物理回调(接触,触发器和关节的归档"的所有阶段") 我需要确定我的前锋游戏对象与其他游戏对象发生了哪些迭代.如果我进行用户自动仿真,则OnCollisionEnter可以工作.但是当我使用Physics时它不起作用,模拟它没有注册.当我的物体与其他物体碰撞时,我在做什么错或怎么办?

I am trying to use physics.simulate in unity. According to unity documentation "simulation includes all the stages of collision detection, rigidbody and joints integration, and filing of the physics callbacks (contact, trigger and joints" I need to get at which iteration does my striker gameobject collides with other gameobject. If I user auto simulation, OnCollisionEnter works. However it doesn't work when I use Physics.Simulate it doesn't register. What am I doing wrong or how do I get when my object collides with other objects.

推荐答案

我们可以使用Physics检测何时发生刚体碰撞. 团结

Can we detect when a rigid body collides using Physics.Simulate in unity

是的,可以.

我曾经对此做过一次实验,但它确实起作用,我打开了使用的相同样本场景,再次进行了测试,然后又再次起作用.这是您的问题中来自文档的一条声明:

I once did an experiment on this and it worked, I opened the-same sample scene used and made the test again and it worked again. Here is an statement from the doc which is also in your question:

模拟包括碰撞检测,刚体的所有阶段 和关节整合,并提交物理回调 (接触,触发和关节).

Simulation includes all the stages of collision detection, rigidbody and joints integration, and filing of the physics callbacks (contact, trigger and joints).

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

So, it can detect collision.

如果我进行用户自动仿真,则OnCollisionEnter可以工作.但是它没有 使用Physics时可以正常工作.模拟它不会注册.

If I user auto simulation, OnCollisionEnter works. However it doesn't work when I use Physics.Simulate it doesn't register.

您不能使用IsSleeping()进行碰撞.假设您已正确设置对撞机和Rigidbody,则问题是maxIterations太小,导致模拟未完成且未到达应该与之碰撞的目标.如果未完成此冲突,则不会调用OnCollisionEnter.

You can't use IsSleeping() to get collision. Assuming you have collider and Rigidbody properly setup then the problem is that the maxIterations value is too small leading to the simulation not being finished and not reaching the destination where it is supposed to collide with another object. If this collision is not done, OnCollisionEnter will not be called.

增加您的maxIterations使其在模拟中具有更大的距离移动,应调用OnCollisionEnter.至于要检测您的GameObject与其他GameObject碰撞的迭代,请使用布尔变量作为标志,并在OnCollisionEnter函数中将其设置为true,然后在此布尔变量为true时将其从for循环中设置为break.

Increase your maxIterations to give it more distance movement in the simulation and OnCollisionEnter should be called. As for detecting which iteration your GameObject collides with other GameObject, use a boolean variable as flag and set it to true in the OnCollisionEnter function then break out of the for loop when this boolean variable is 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不能解决您的问题,请查看


If increasing maxIterations did not solve your issue then look into time based simulations. It will do the simulation in x seconds. 5 seconds is used in the code below and the only thing changes is the RunSimulation() function. The rest of the code above is still valid:

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

这篇关于我们可以使用Physics检测何时发生刚体碰撞.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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