是否可以每帧多次调用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()被调用...所以我可以计算每帧一个粒子的邻居。
感谢您的帮助!
答案 0 :(得分:0)
是否可以每帧多次调用OnParticleTrigger()?
不,即使可能,您也不应该调用任何Unity回调函数。
你应该查看Unity的ParticlePhysicsExtensions
类,它具有GetTriggerParticles
功能,可以帮助你做到这一点。
这很棘手,但可以通过以下步骤完成:
将Sphere GameObject与Sphere Collider一起使用。您可以使用此球体碰撞器确定哪些粒子彼此更接近。球体内的任何粒子都被认为更接近球体内的其他粒子。
1 。创建一个Sphere,然后插入粒子系统中触发器模块中的 Colliders 插槽。将其定位到应检测粒子的位置,然后禁用其Mesh Renderer
。
2 。在触发器模块上,确保内部,外部, Enter < / em>和退出设置为回拨。
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;
}