ParticleSystem使用OnParticleTrigger()查找相邻粒子

时间:2017-02-11 19:00:32

标签: c# unity3d

是否可以每帧多次调用OnParticleTrigger()

我正在研究一个粒子系统,其中每个粒子都将它计算为邻近粒子并相应地对其起作用。 为此,我创建了一个带有圆形碰撞器2D(游戏是2D)的空游戏对象,并将其位置迭代到每个粒子位置。

这样就可以为每个粒子调用OnParticleTrigger()函数,并计算此粒子位置的邻居。然后跳转到粒子系统的下一个位置。我想拥有多达10 000个粒子,这就是为什么我不想为每个粒子创建一个对撞机。然而,到目前为止,我只是成功地计算了每帧一个分区的邻居,因为Unity的PhysicsEngine只给了我一帧触发信息。

任何想法如何多次调用它?或者,如果在Unity粒子系统中有一个更简单的计算邻居粒子的解决方案,我也是开放的:D

         //In update: iterating over all particle positions at each frame
         InitializeIfNeeded();
         numParticlesAlive = m_System.GetParticles(m_Particles);
         while (h < numParticlesAlive)
         {
             if (triggered)
             {
                 Colly.transform.position = m_Particles[h].position;

                 cp = m_Particles[h].position;
                 h++;
                 triggered = false;

             }

         }

这样,每帧只有一个对撞机位置,函数void OnParticleTrigger()被调用...所以我可以计算每帧一个粒子的邻居。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

  

是否可以每帧多次调用OnParticleTrigger()?

不,即使可能,您也不应该调用任何Unity回调函数。

你应该查看Unity的ParticlePhysicsExtensions类,它具有GetTriggerParticles功能,可以帮助你做到这一点。

这很棘手,但可以通过以下步骤完成:

将Sphere GameObject与Sphere Collider一起使用。您可以使用此球体碰撞器确定哪些粒子彼此更接近。球体内的任何粒子都被认为更接近球体内的其他粒子。

1 。创建一个Sphere,然后插入粒子系统触发器模块中的 Colliders 插槽。将其定位到应检测粒子的位置,然后禁用其Mesh Renderer

2 。在触发器模块上,确保内部外部 Enter < / em>和退出设置为回拨

enter image description here

3 。使用

获取刚进入球体内的粒子

ParticlePhysicsExtensions.GetTriggerParticles(mainParticle, ParticleSystemTriggerEventType.Enter, enter);

4 。浏览球体内的粒子(来自#3 的粒子):

在每个循环中:

A 。将球体位置移动到当前粒子循环

B 。使用

获取球体内的粒子
ParticlePhysicsExtensions.GetTriggerParticles(mainParticle, ParticleSystemTriggerEventType.Inside, neighbouringParticles);

这些被认为是相邻的粒子。在此之后,只需将球体移回其默认位置。

以下是您应该做的一个示例:

public GameObject SphereParticleCollider;

List<ParticleSystem.Particle> enter = new List<ParticleSystem.Particle>();
List<ParticleSystem.Particle> neighbouringParticles = new List<ParticleSystem.Particle>();
ParticleSystem mainParticle;

private void Start()
{
    mainParticle = GetComponent<ParticleSystem>();
}

void OnParticleTrigger()
{
    //Get particles that entered 
    findEnteredParticles();

    //Get neighbouring particles 
    findNeighbouringParticles();
}

void findEnteredParticles()
{
    if (mainParticle == null)
    {
        mainParticle = GetComponent<ParticleSystem>();
    }
    ParticlePhysicsExtensions.GetTriggerParticles(mainParticle, ParticleSystemTriggerEventType.Enter, enter);
}

void findNeighbouringParticles()
{
    //Get default Spehere Collider position
    Vector3 currentParticleCollider = SphereParticleCollider.transform.position;

    //Find particles that are Neighbour of each particle that entererd
    for (int i = 0; i < enter.Count; i++)
    {
        //Move Spehere Collider to the positon of each particle that enetered
        SphereParticleCollider.transform.position = enter[i].position;

        //Finally get all particles that are inside the Sphere. These are considered to be near the particle
        ParticlePhysicsExtensions.GetTriggerParticles(mainParticle, ParticleSystemTriggerEventType.Inside, neighbouringParticles);

        //Loop through and do something with each neighbouring particles 
        for (int j = 0; j < neighbouringParticles.Count; j++)
        {
            ParticleSystem.Particle neighbourParticles = neighbouringParticles[j];
            //.....
            //......
            //.....
            Debug.Log("Found neighbouring particles!");
        }
    }

    //Reset the position of the Spehere Collider position
    SphereParticleCollider.transform.position = currentParticleCollider;
}