Simulating a starling murmuration

Starlings

A recurrent question about UnitySteer is how to implement behavior like that of a flock of starlings (seems that Mr. Reynolds was right on the money when he chose flocking for his paper).

Usually the person who writes mentions that their implementation is “getting there”, but they’re not quite happy with the result yet. The main issue with the question is that if the results are right or not are all about perception - it’s not a problem where there is a single, provably optimal solution.

With that in mind, I’ll detail some of the aspects of the starlings from the video above, and mention how you can mimic them in UnitySteer.

UnitySteer acceleration smoothing changes

UnitySteer currently has an acceleration smooth rate parameter on TickedVehicle. It’s used to indicate the percentage of the velocity that is actually applied every frame to the current smoothed acceleration.

There’s two major issues with this:

  • It’s framerate dependent, making vehicle behavior effectively non-deterministic.
  • It makes it impossible to describe acceleration in the terms that people are used to thinking of them, for example 0 to 60 in 5 seconds.

The latter could be handled as an independent behavior or control, which gradually increases the maximum speed for the vehicle, but the former is a definitely something I want to address. And since I’m going to be working on that, I might as well implement the gradual acceleration as well.

The approach I’m thinking of following is adding two properties to AutonomousVehicle for maximum acceleration and deceleration per second. These would be evaluated on CalculatePositionDelta, so that the vehicle implementation can control its own acceleration style.

The only issue with this is that at the point that method is called, we have already assigned a speed to the vehicle when UpdateOrientationVelocity is called. This means the vehicle is supposedly moving at the full velocity, even if not necessarily all of it is being applied.

Overall, it looks like the necessary changes then are:

  • Remove accelerationSmoothRate altogether, to eliminate the framerate dependent behavior.
  • Add properties for maximum acceleration/deceleration per second to AutonomousVehicle.
  • Not set Speed immediately, and instead save it on DesiredSpeed parameter (which is currently pretty much unused).
  • When CalculatePositionDelta is called, we gradually lerp Speed to DesiredSpeed based on the time delta.
  • Keep the Velocity property on AutonomousVehicle as is – defined as a function of the forward vector and the current speed.

This also has the advantage that it lets us simulate a bit of inertia, where it takes a vehicle a while to stop. It will be a major change and will have an effect on how your agents behave, so keep it in mind before upgrading.