- Home /
How does particle.velocity relate to the particle's actual velocity?
This question is about Shuriken particle systems. Based on my experiments it appears that the velocity property of a ParticleSystem.Particle object only reflects the constant Start Speed from the Main Particle System module, and does not account for any velocity changes from other modules. For example, here the start speed is set to 1:
Also, the system includes a Velocity Over Lifetime setting like so:
I use GetParticles() on the system in the Update() method and print the velocity, but the result is always just the velocity set by the Start Speed value, though I can clearly see the particles moving at different rates.
velocity=(0.0, 1.0, 0.0)
UnityEngine.MonoBehaviour:print(Object)
Is this the expected result? If so, is there any way to get the actual velocity for a given particle at any moment?
For other particle properties like size and color there are the GetCurrentSize() and GetCurrentColor() methods. Also, those properties are named startSize and startColor, making it clear that they are not necessarily the current value over the lifetime of the particle. I assumed that since velocity was simply called "velocity" and that since there is no GetCurrentVelocity(), that it contained the actual current value. But it appears this is not the case?
Thanks for your help!
Answer by richardkettlewell · Sep 07, 2017 at 08:32 AM
Hi Malveka,
We store 2 types of velocity per particle:
persistent velocity
animated velocity
The persistent velocity persists across frames. eg the Force module applies a force, this gets applied to the velocity, and then that velocity is remembered between frames. Another great example of this is Start Velocity. It is applied once at the start, and remembered afterwards on each frame.
The animated velocity is used for non-physics effects (noise, velocity over lifetime, etc). This velocity is not remembered across frames, because these modules calculate a new velocity value each frame.
Unfortunately, the script only allows you to access the persistent velocity, and not the animated velocity. I will look at adding an accessor for this in a future version.
Until then, if you are using a JIT platform, you may be able to use Reflection to access this "secret" property. See https://stackoverflow.com/questions/95910/find-a-private-field-with-reflection
Something like:
var prop = particle.GetType().GetField("m_AnimatedVelocity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
prop.SetValue(particle, "new value");
This will not work on AOT platforms (eg Consoles, or Android with Mono), but it will work on JIT platforms (eg PC)
Good luck!
Thanks Richard! That's very helpful. $$anonymous$$nowing that there are two different velocity values goes a long way towards enabling me to make sense of the behavior I've been seeing. :^)
Does the animated velocity incorporate persistent velocity? Or do the persistent and animated need to be combined in some way to get the actual velocity?
And, if I can sneak in one more question... What other particle properties have the same implementation (i.e. persistent and animated values)? AngularVelocity? AngularVelocity3D?
Just add Velocity to animatedVelocity to get the total. I've added some script properties for this today :)
We don't have any other properties that are split like this.
Excellent! This information is so helpful. Once again, thank you! Looking forward to when those properties are available. :^)
Any update on being able to modify particle.animatedVelocity? I'm trying to change a particle's direction after it has been created using particle.velocity and I'm not having any luck...
Hi, the only update is that it's not trivial to make it writable, because it is reset every frame, and the order of the simulation doesn't make it usable in script:
Native update (build animatedVelocity)
Native update (apply animatedVelocity and reset it to zero)
Script Update (too late, animatedVelocity was already calculated and applied)
Script LateUpdate (far too late!)
So for now it will only be readable.
Changing the direction of a particle after birth is possible unless you are overwriting it with the Velocity over Lifetime module.
Interesting... thanks for the update! That's actually pretty helpful in understanding how the velocities relate to one another...
As an aside, for my purposes, I didn't need to modify animated velocity. I think my problem was unrelated to velocity in general (I'll mention it here in case someone finds it helpful). After many, many hours of trial and error and reading forum posts... basically I needed to use ParticleSystem.Emit(emitParams, count)
to create my particles manually and set their position if I wanted to also modify their Particle.velocity at will. Previously I was trying to recreate the entire array every time it updated (as per Live Training 11-decals section), but it seemed like the system wasn't simulating, because even if I set their velocities they wouldn't move. $$anonymous$$uch better to let the ParticleSystem handle its own emissions with me giving it parameters as necessary.
Anyway, thanks again, @richardkettlewell for helping us understand this stuff more completely! If there's any way to recommend that someone do another, deeper set of Live Sessions on manually manipulating particles, that would be absolutely stellar. There are a lot of pitfalls and optimization tricks that are buried pretty deep in the internet.
Cheers!
Answer by ifurkend · Sep 06, 2017 at 10:46 PM
Just very recently I have the same question and after few testing, Particle.velocity ignores (or its sum is calculated before) "velocity over lifetime", "inherit current velocity" and "noise". Other than these 3, "start speed", "gravity modifier", "limit velocity over lifetime", "inherit initial velocity", "force over lifetime" (randomized or not) and collision are all accounted to Particle.velocity. @Richardkettlewell or @karl_jones could shed some light, perhaps...
Thanks for the reply! I need to do some more tests. Also, the link to the forum thread is especially helpful since there are some Unity developers participating there.