I have a what I thought was going to be trivially simple situation where I want (shuriken) particles to bounce away (in a particular manner) and start spinning in response to hitting a collider.
I tackled the bounce part first.
- set up Particle System
- enable Trigger module
- attach script, catch OnParticleTrigger
- GetTriggerParticles, iterate, assign new .velocity, SetTriggerParticles
This much works just fine- particles hit the collider, and on enter, they get plinked away exactly where I tell them to go. So the fundamentals of the read-write-update flow are sound.
Now, I wanted to add rotation for a bit more visual energy.
I tried updating .angularVelocity right after I update .velocity. A Debug.log shows the new value, but the particles don’t spin.
I tried turning on the Rotation over Lifetime module in case that somehow enabled dynamic update calculations. Particles spin globally, and I can see the RoL values showing up in debug logging, and I can see my new values after I assign them, but the particles still only visually rotate in accordance with the RoL-initialized value.
I tried both of the above with the z-axis of split-axis .angularVelocity3D with essentially identical result.
Is it simply not possible to change a particle’s spin speed after emission in Unity (2019.4.14f1) without building a full custom VFX Graph solution, or am I missing a flag somewhere to tell shuriken to actually write back angularVelocity changes and use them in system updates?
Yep, there’s some sort of bug. I just tried to get it to work with a vanilla particle system and nothing happens, so I started playing around with the modules. Nothing was still working until I first enabled Rotation Over Lifetime, disabled it, and then everything started working as you’d expect. You might want to file a proper bug report.
Here’s a working code based solution / workaround:
public sealed class ChangeAngularVelocity : MonoBehaviour
{
private void Start()
{
StartCoroutine(Tick());
}
private IEnumerator Tick()
{
ParticleSystem particleSystem = GetComponent<ParticleSystem>();
ParticleSystem.Particle[] particles = new ParticleSystem.Particle[particleSystem.main.maxParticles];
// UNCOMMENT THIS SECTION AND EVERYTHING WILL WORK:
/*
ParticleSystem.RotationOverLifetimeModule rotationOverLifetime = particleSystem.rotationOverLifetime;
rotationOverLifetime.enabled = true;
yield return null; // you have to wait a frame or it won't work
rotationOverLifetime.enabled = false;
*/
while (enabled == true)
{
int count = particleSystem.GetParticles(particles);
for (int i = 0; i < count; ++i)
{
particles[i].angularVelocity = Random.Range(0f, 360f);
}
particleSystem.SetParticles(particles, count);
Debug.LogFormat("Changed {0} particles", count);
yield return new WaitForSeconds(0.2f);
}
}
}
You absolutely have to wait a frame before disabling it or it won’t work.
Particle system with enabling/disabling commented out:
Particle system with enabling, yielding a frame, disabling:
Yep please give us a bug report 
Thanks! I may need to just inline GroZZler’s sample into the report. Notwithstanding NDA, by the time I find these things it’s usually in a project with a million other dependencies that takes upwards of 5 mins just to open, and reducing it to an isolated repro case can be hell.