Particle are rotating with the emitter

I am surprised that no one has asked this yet. So im making a rocket game where you can thrust and rotate the rocket left and right. I have applied all particle effects properly and they are triggering when required but the explosion particle effect is rotating along with the rocket

ezgif.com-video-to-gif

These are my particle settings

There are multiple particle effects in the same effect

PLEASE HELP!!

I want the smoke to go up but its rotating along with the rocket

It happens because the emitter is rotating along with the rocket and it is emitting particles in its ‘local up’ (or whichever way you configured it, but local to itself). You have the simulation space set to ‘World’ but it’s only once the particles have been spawned - and are moving in the direction they have been told to move by the emitter - that they are simulated in world space. Their direction has already been set.

The easiest way to fix it is to disconnect the particles from the rocket when it crashes. When you play the particles, set its parent to null first, and perhaps reset the rotation because the rocket will likely be rotated when crashing and the emitter would be rotated then, too.

crashParticles.transform.SetParent(null, false); // <-- Add this here
crashParticles.Play()

This will disconnect the particles from the ship and allow the ship to rotate without affecting the particles. The false at the end of SetParent(null, false) is important. See, the documentation here.

Nope this does not seem to be working

Now there is a new problem
I rotated the particles to face upwards but something weird is going on

ezgif.com-video-to-gif

I set the simulation scale from world to local but still its the same

How are you restarting the level? This is happening because you disconnected the particles from the rocket and then it appears the rocket is just moved back to the start and the particles stopped. If you reload the scene like we do in the course it should all be reset again because everything is just reloaded. If you are just moving the rocket back to the starting platform and stopping the particles, you’d have to reconnect the particles to the rocket the way it was before, or move them to the new collision point before playing them.


Edit
I’m wrong. When you disconnect the particles using SetParent(null, false) the particles are moved to (0,0,0) - or whatever the particle system’s local transform is set to. You should move them to the rocket just before playing them. You could use SetParent(null) or SetParent(null, true) but that would also affect the scale and rotation of the emitter

crashParticles.transform.SetParent(null, false);
crashParticles.transform.position = [rocket].transform.position; // <-- get the rocket's position
crashParticles.Play();

You need the rocket’s position. You can probably just pass it to StartCrashSequence like this

default:
    StartCrashSequence(other.transform.position);
    break;

and update the method’s signature

void StartCrashSequence(Vector3 position)
{
    // ... other code
    crashParticles.transform.SetParent(null, false);
    crashParticles.transform.position = position; // <-- get the rocket's position
    crashParticles.Play();
    // ... remaining code
}

Another Edit
We can get away without passing the position. Let’s disconnect the particles and keep their world stuff, then just rotate them to face up

void StartCrashSequence()
{
    // ... other code
    crashParticles.transform.SetParent(null, true); // <-- this is true now
    crashParticles.transform.rotation = Quaternion.identity; // <-- reset the rotation
    crashParticles.Play();
    // ... remaining code
}

This will only work if the emitter’s original local rotation is (0,0,0)


Yet Another Edit
I didn’t realise that the CollisionDetector is on the rocket. We already have the rocket position

void StartCrashSequence()
{
    // ... other code
    crashParticles.transform.SetParent(null, false);
    crashParticles.transform.position = transform.position; // <-- set the rocket's position
    crashParticles.Play();
    // ... remaining code
}

This will do the trick. You may need to set the y to 0

var position = transfom.position;
position.y = 0; // set y to ground y - assume 0 for now
crashParticles.transform.position = position;

I tried going through the documentation but i didnt understand the use of “false” in SetParent() function

Apart from that its working
Thank you sooo much!!

EDIT:

I tried but it just seems to be working like before
Dunno what it actually does

The transform of a child object is relative to its parent, so when the transform position is (0,0,0) it is exactly at the same position as the parent. When it’s (1,0,0) it is shifted 1 unit on the x-axis from where the parent is in the world. If the parent is at (10,0,5) the child is at (11,0,5) in the world - but it’s transform is set to (1,0,0).

When you use SetParent with false, that (1,0,0) stays the same. Set the parent to null, and the child moves to (1,0,0) in the world. Set the parent to another object at (5,12,4) and the child’s transform stays (1,0,0) but its world position becomes (6,12,4) - shifted 1 unit on the x-axis from where the parent is in the world.

When you use SetParent with true, the transform is adjusted to keep the object at the same location, with the same rotation and scale. Using our (10,0,5) parent again, setting the parent to null will change the child’s (1,0,0) position to become (11,0,5). Had we set it to the other object at (5,12,4) the position would become (6,-12,1) so that its position relative to its new parent would keep it at the (11,0,5) world position it had before SetParent.

I hope that made sense…

Not sure what this bit means. Is it working now, or not?

Privacy & Terms