- Home /
OnParticleCollision Question (Image included) Particle Decal Hanging off Edge
I want to be able to tell if where the particle hits is within the bounds of the object it hit subtracted by the max size of the splatter that will be displayed on the hit object. This way if the splatter is hanging off the edge of the hit object it can be destroyed instead. But it doesn't seem like its possible to determine where OnParticleCollision hit outside of worldspace. Does anyone know of a way I can tell where the collision occurred relative to the object that the particle collided with.
If that doesn't make sense then does anyone know another way to detect and remove particle decals when they're hanging off the edge of an object.
Here is an image of what I'm talking about : https://i.imgur.com/HUYKXvB.png
I am using the following system slightly modified for my Splatter effect so you can view the code here: https://unity3d.com/learn/tutorials/topics/scripting/drawing-decals-particles
I don't want to do anything fancy like wrapping it or moving it. Just destroying / not spawning it is fine.
void OnParticleCollision(GameObject other)
{
ParticlePhysicsExtensions.GetCollisionEvents(particleLauncher, other, collisionEvents);
for (int i = 0; i < collisionEvents.Count; i++)
{
//The if statement would probably go here
splatDecalPool.ParticleHit(collisionEvents[i], particleColorGradient);
EmitAtLocation(collisionEvents[i]);
}
}
Thank you!
Answer by Razputin · Apr 01, 2018 at 10:57 PM
Alright I ended up adding a transform to the ParticleDecalData, spawning an empty gameobject on the point of collision then setting the empty gameobjects size/rotation/position equal to that of the particle image, then taking that transform and filling it in to the particledecaldata transform. Then firing a raycast opposite of whichever way the transform was pointing on all 4 sides. If all 4 sides collide with something, it means they're all touching the wall and the image can be displayed without any edges hanging off. Otherwise I just shrink the image to a size of 0 so it can't be seen.
void SetParticleData(ParticleCollisionEvent particleCollisionEvent, Gradient colorGradient)
{
if(particleDecalDataIndex >= maxDecals)
{
particleDecalDataIndex = 0;
}
particleData[particleDecalDataIndex].position = particleCollisionEvent.intersection;
Vector3 particleRotationEuler = Quaternion.LookRotation(particleCollisionEvent.normal).eulerAngles;
//particleRotationEuler.z = Random.Range(0, 360);
particleData[particleDecalDataIndex].rotation = particleRotationEuler;
particleData[particleDecalDataIndex].size = Random.Range(decalSizeMin, decalSizeMax);
particleData[particleDecalDataIndex].color = colorGradient.Evaluate(Random.Range(0f, 1f));
GameObject temp = new GameObject();
particleData[particleDecalDataIndex].transform = temp.transform;
particleData[particleDecalDataIndex].transform.rotation = Quaternion.LookRotation(particleCollisionEvent.normal);
particleData[particleDecalDataIndex].transform.position = particleData[particleDecalDataIndex].position;
particleData[particleDecalDataIndex].transform.localScale = new Vector3(particleData[particleDecalDataIndex].size, particleData[particleDecalDataIndex].size, particleData[particleDecalDataIndex].size);
Debug.Log(particleData[particleDecalDataIndex].transform.localScale);
Destroy(temp);
CheckRaycast(particleDecalDataIndex);
particleDecalDataIndex++;
}
void CheckRaycast(int particleDecalDataIndex)
{
float size = particleData[particleDecalDataIndex].size / 2;
Vector3 fwd = particleData[particleDecalDataIndex].transform.forward;
if (Physics.Raycast(new Vector3(particleData[particleDecalDataIndex].position.x - size, particleData[particleDecalDataIndex].position.y, particleData[particleDecalDataIndex].position.z), -fwd, 2, mask)
&& Physics.Raycast(new Vector3(particleData[particleDecalDataIndex].position.x + size, particleData[particleDecalDataIndex].position.y, particleData[particleDecalDataIndex].position.z), -fwd, 2, mask)
&& Physics.Raycast(new Vector3(particleData[particleDecalDataIndex].position.x, particleData[particleDecalDataIndex].position.y, particleData[particleDecalDataIndex].position.z - size), -fwd, 2, mask)
&& Physics.Raycast(new Vector3(particleData[particleDecalDataIndex].position.x, particleData[particleDecalDataIndex].position.y, particleData[particleDecalDataIndex].position.z + size), -fwd, 2, mask)
)
{
Debug.Log("Touching All Points");
}
else
{
Debug.Log("Missing");
particleData[particleDecalDataIndex].size = 0;
}
}
If anyone can think of a better solution that'd be great though.