Search Unity

Question Add velocity additively in ParticleSystem.Emit

Discussion in 'General Graphics' started by Vincent454, Jan 18, 2022.

  1. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    Hello, I've been trying to add a velocity to the particles I emit in particleSystem.Emit()

    I have been trying three methods so far to achieve this, sadly none of them worked out:

    1: To use the "Inhertit Velocity" module and give the particle system a kinematic rigidbody that I change the velocity of before emitting. This did not change anything even though a Debug.Log tells me that the rigidbody velocity has changed - I guess its because the particle system emits after the rigidbody notices its kinematic and resets the velocity to 0 again? When setting it to non-kinematic this creates glitchy movement of particles where they sometimes use the velocity and sometimes seemingly dont. It also does not work if multiple particles are emitted in 1 frame as they will use the same velocity in the end.

    2: I tried to use the "Velocity Over Lifetime" module, but this will also have all already emitted particles change their velocity

    3: When using velocity = X in the emit params, the velocity of other modules is overwritten completely

    Does anyone have an idea on how to do this?
    My use case is, if an enemy gets hit, I want to emit a particle effect that uses their velocity at the start so they dont just spawn and stay in the air, but move in the direction that enemy moved in when they got hit.
    Maybe there is a start velocity parameter I am not able to find?
     
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    The shape module and start speed (main module) dictate the initial velocity vector.
    You can make changes to the settings, call Emit, and then restore the old settings, if you need to ensure the changes are only temporary for the current scripted emission.

    For example, https://docs.unity3d.com/ScriptReference/ParticleSystem.ShapeModule-rotation.html may be very useful to you. There are Mathf helper functions to build a rotation quaternion from desired direction vector, i believe.
     
    Vincent454 likes this.
  3. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    Thank you very much for your quick support, I am actually doing that already, I should have explained it better:

    Code (CSharp):
    1. ParticleSystem.ShapeModule shape = effect.particleSystem.shape;
    2. shape.rotation = rotationToPlayEffectAt.eulerAngles;
    3. effect.particleSystem.Emit(new ParticleSystem.EmitParams
    4. {
    5. position = positionToPlayEffectAt,
    6. applyShapeToPosition = true,
    7. }, 1);
    This is my setup right now. I want to additively apply the velocity, so it uses the shape module and adds the velocity on top - similar to how it would behave if I instantiated the particle system in local simulation space as a child of the object whichs velocity I am using.

    particle.png

    Is something like this possible?
     
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    One way would be to apply the velocity manually on top of the shape.rotation you are already setting.

    Maybe something like:
    * https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html or https://docs.unity3d.com/ScriptReference/Matrix4x4.LookAt.html (whatever gives the same type as rotationToPlayEffectAt)
    * multiply rotationToPlayEffectAt by the value you built in step 1
    * get the eulerAngles of this final value and assign it to shape.rotation
    * finally, do main.startSpeed *= yourVelocityVector.length
     
  5. Vincent454

    Vincent454

    Joined:
    Oct 26, 2014
    Posts:
    167
    I accidentally posted an unfinished reply trying to reformat my pasted code with tab tab space lol. Now I have to write everything again xD

    This seems to work almost, but the velocity of the emitted particles is still wrong - or maybe not, but the rotation isn't working I believe. What does multiplying the quaternions do, I dont quite understand this part. I am using a cone shape on my particle systems.

    I've been thinking if maybe interpolating between both rotations based on the velocityToAdd percentage of both velocities combines could help, but if the velocity to add had a near 100% percentage, the cone would be rotated too much, and - in case of the cube examble above would emit inside the cube.

    This is my code now:
    Code (CSharp):
    1. ParticleSystem.ShapeModule shape = effect.particleSystem.shape;
    2.         ParticleSystem.MainModule main = effect.particleSystem.main;
    3.  
    4.         if (velocityToGiveEffect != Vector3.zero)
    5.         {
    6.             shape.rotation = (rotationToPlayEffectAt * Quaternion.LookRotation(velocityToGiveEffect)).eulerAngles;
    7.             main.startSpeedMultiplier = velocityToGiveEffect.magnitude;
    8.         }
    9.         else
    10.         {
    11.             shape.rotation = rotationToPlayEffectAt.eulerAngles;
    12.             main.startSpeedMultiplier = 1;
    13.         }
    Also using startSpeedMultiplier changes the second value I am using in startSpeed set to randomBetweenTwoConstants

    Thanks a lot for your help! If helping to solve this problem is too much work - It is not that important in my game, most if not all games dont really care about this, but I thought it would be nice to have. But maybe this is just not possible to do?