Correct way to place particle emissions at contact point? EmitParams.position bugged?

Trying to spawn a particle effect on impact. I have a particle system on my ship operating in world space and call a script to spawn particles on a 2D collision.

How am I supposed to position the particles? I was thinking system.emit(emissionparams.position) but that’s overriding the particle system. Do I literally just move the particle emitter’s transform to the contact point and then emit?

Also, do you have to manually reference secondary particle systems (child objects) to emit or is there a way to combine the two in a single call, so when the first fires it also triggers the second?

You can call Emit with an override to give the particles a new position https://docs.unity3d.com/ScriptReference/ParticleSystem.EmitParams.html
This will only override it for this emit call, so its the right thing for what you need.
You could also spawn a new particle system at that location, if its a collision point then this is also fine.
You could also just grab the particle with GetParticles and manually set the positions.

If they are set as subemitters then they will work with the Emit call and wont need any additional calls.

4 Likes

Cool. This leads on to a better idea than I was doing for common effects like collision sparks which is to have one universal Shuriken system at the root level and call Emit(pos) with the collision (or whatever) position. Saves a bit of object creation and cleanup versus per-object effects.

Hang on, that’s what I was doing in my OP and it isn’t working. No particles appear when I supply a position to the emitparams.

    public ParticleSystem FX_sparks;
    ParticleSystem.EmissionModule FX_em_sparks;
    ParticleSystem.EmitParams FX_params_sparks;

    void Awake(){
        instance = this;
        FX_em_sparks = FX_sparks.emission;
        FX_params_sparks = new         ParticleSystem.EmitParams();
    }
  
    public void Sparks(Vector2 pos, int count){
        print("spark at "+pos+"   "+count);
        FX_params_sparks.position = Vector3.zero;
        FX_sparks.Emit(FX_params_sparks, count);
    }

If I change FX_params_sparks.position, no particles are emitted. If I comment out that line, particles are emitted. If I use other params like size, they work so long as I don’t change position. That’s spawning particles at (0,0,0) - if I print out FX_params_sparks.position without changing it, it’s (0,0,0).

Working from the manual example, this code spawns a red particle upwards with no variation of trajectory. It seems all the properties for direction are zero’d when position is changed.

2888812--212306--Image1.jpg

Create a new scene. Add a blank GO. Add this script. Run…

using UnityEngine;

// In this example, we have a particle system emitting green particles; we then emit and override some properties every 2 seconds.
public class EmitExample : MonoBehaviour
{
    public ParticleSystem system;

    void Start()
    {
//        // A simple particle material with no texture.
//        Material particleMaterial = new Material(Shader.Find("Particles/Alpha Blended Premultiply"));

        // Create a green particle system.
        var go = new GameObject("Particle System");
        go.transform.Rotate(-90, 0, 0); // Rotate so the system emits upwards.
        system = go.AddComponent<ParticleSystem>();
//        go.GetComponent<ParticleSystemRenderer>().material = particleMaterial;

        // Every 2 secs we will emit.
        InvokeRepeating("DoEmit", 2.0f, 2.0f);
    }

    void DoEmit()
    {
        // Any parameters we assign in emitParams will override the current system's when we call Emit.
        // Here we will override the start color and size.
        var emitParams = new ParticleSystem.EmitParams();
        emitParams.position = Vector3.zero;
        emitParams.startColor = Color.red;
        emitParams.startSize = 0.2f;
        system.Emit(emitParams, 10);
        system.Play(); // Continue normal emissions
    }
}

The default particle system sprays a cone of white particles upwards. Every two seconds, 10 overlapping particles are emitted that travel straight up from centre. Comment out the line “emitParams.position = Vector3.zero;” and 10 red particles are sprayed in the cone according to the system emission shape.

Bug?

Try this: Unity - Scripting API: ParticleSystem.EmitParams.applyShapeToPosition

1 Like

Fixed. Thanks! I see this is actually mentioned on the params.position page… :sweat_smile:Although to be fair on myself, the particles weren’t appearing so I wasn’t aware they were losing their shape and projection.

1 Like

Is there anyway to pass on the rotation of the emission shape. i’m using a similar system as above, but am emitting particles in cone shape. but i want to pass on a rotation for the cone along with a position…is this possible?

It’s possible by modifying the shape module transform before calling Emit… something like:

var shape = ps.shape;
shape.rotation = myRotation;
ps.Emit(1, myEmitParams);

you may want to restore the old rotation afterwards, depending on what you’re doing :slight_smile:

thats the method i went for currently.
There is a issue though. As there are mutlple gameobjects with the script that calls the particle system “emit”, some particles come out at the wrong rotation. Its as if all of the emit commands are sent in one go, so if 2 script call the emit function and rotate the system, both emit particles face the same direction, ignoring one of the rotations…

I’m trying to use the emit function as a means of have a single aprticle system for bullet impacts, and other simialr repeating spot vfx. Is there a better method for doing this currently?

That shouldn’t happen. If you can prove it in a repro project, report it as a bug and I’ll see what’s going on. You can link to this forum thread in your bug report, and reply here with the case number, to help connect the dots :slight_smile:

That’s the best way, yeah.

1 Like

It surely happens (and other odd things) in EditMode if the ParticleSystem.Emit function is called in LateUpdate.
Here is a very simple test case, just moving one of the spheres in the attached scene should show the issue.

4576591–425920–EmitParamsGlitch.unitypackage (8.74 KB)

To be clear, report it as a bug means this: https://unity3d.com/unity/qa/bug-reporting

1 Like