Advancing State Machines
Advancing and Performance Considerations
In the render loop, as we’ve seen in previous sections, the essential goal of each frame is to:
- 1.Make the
Renderer
- 2.Advance relevant
StateMachine
instances by an elapsed amount of seconds since the last frame paint - 3.Draw relevant
Artboard
instances with the renderer
In many of our examples previously, we’ve called
.advance(elapsedSeconds)
on a single StateMachine
instance, which moved the animations forward over time. With the Rive GameKit, there are multiple ways to advance state machines in a performant way, as well as draw the artboard.StateMachine
classvoid advance(double elapsedSeconds)
- Description: Advances the timeline animations on a singular
StateMachine
instance. - When to use: If you have just a few
StateMachine
instances in your scene, it should be fine to simply call this and separately render yourArtboard
- Example:
bool paint(rive.RenderTexture texture, Size size, double elapsedSeconds) {// Advance a single state machine by elapsedSecondsstateMachine.advance(elapsedSeconds);}
Rive
classstatic void batchAdvance(Iterable<StateMachine> stateMachines, double elapsedSeconds)
- Description: Advances the timeline animations on a list of
StateMachine
instances by splitting the work up among multiple threads in a worker thread pool - When to use: If you have a large amount of
StateMachine
instances in your scene that you want to advance all at the same time, this can be a more performant solution. If the state machine’s associatedArtboard
does not need to be drawn with theRenderer
but still needs to be advanced, use this method. If you do need to render the associatedArtboard
, see thebatchAdvanceAndRender
method below. - Example:
final Set<rive.Artboard> allZombieArtboards = {};final Set<rive.StateMachine> allZombieStateMachines = {};void populateZombies() {for (int i = 0; i < 1000; i++) {var artboard = riveFile.artboard("Zombie Man")!;allZombieArtboards.add(artboard);allZombieStateMachines.add(artboard.stateMachine("Motion")!);}}bool paint(rive.RenderTexture texture, Size size, double elapsedSeconds) {// Advance a list of state machines by elapsedSecondsrive.Rive.batchAdvance(allZombieStateMachines, elapsedSeconds);// Make a renderer.final renderer = rive.Renderer.make();// Only draw half the zombiesfor (int i = 500; i < 1000; i++) {var artboard = allZombieArtboards.elementAt(i);renderer.save();renderer.transform(rive.Mat2D.fromTranslate(size.width / 2, size.height / 2));artboard.draw(renderer);renderer.restore();}}static void batchAdvanceAndRender(Iterable<StateMachine> stateMachines, double elapsedSeconds, Renderer renderer)
- Description: The same as
batchAdvance()
but also renders each of the state machine’s associatedArtboard
instances with the passed-inRenderer
instance. The renderer also makes a transformation before drawing using theArtboard
'srenderTransform
property, which is aMat2D
. You can set this property at any time. - When to use: Same as for using
batchAdvance()
but also for performantly drawing theArtboard
with theRenderer
. - Example:
final Set<rive.StateMachine> allZombieStateMachines = {};// Set transformation to translate to a random location on the screenrive.Mat2D setRandomTranslation(rive.Artboard artboard) { . . . }void populateZombies() {for (int i = 0; i < 1000; i++) {var artboard = riveFile.artboard("Zombie Man")!;artboard.renderTransform = setRandomTranslation(artboard);allZombieStateMachines.add(artboard.stateMachine("Motion")!);}}bool paint(rive.RenderTexture texture, Size size, double elapsedSeconds) {// Make a renderer.final renderer = rive.Renderer.make();// Advance a list of state machines and render their artboardsrive.Rive.batchAdvanceAndRender(allZombieStateMachines,elapsedSeconds,renderer);}
In addition to the few
advance()
functions above, there are other techniques that you should be considerate of at design time to keep your game performant.- Don't use the even-odd fill rule. If you need to cut a hole in a shape, make sure to wind the path the opposite direction
- Don't enable the artboard clip option
- Don't nest an artboard inside a clip
- While clipping should be performant in your games when drawing, try to use it as a last resort if you can achieve similar effects another way
Last modified 1mo ago