Skip to content

Multiple state machines with data binding using one view model in a single rive file #599

@iliosana

Description

@iliosana

My goal is to run a rive animation in my flutter application. I have one rive file which includes several state machines (e.g. Lamp and Snow), one view model with multiple boolean properties (e.g. LightBoolean, SnowBoolean). It uses data binding to transition between the state machine states using the boolean properties from the view model. The state machine Lamp uses the boolean property LightBoolean and the Snow state machine the property SnowBoolean to transition between states.

This is my Rive Widget, where controller has type: RiveWidgetController?

controller == null
    ? const Center(child: CircularProgressIndicator())
    : RepaintBoundary(
        child: RiveWidget(
            controller: controller!,
            fit: Fit.cover,
            ),
    ),

In the initState method I'm setting up all ViewModelInstances and ViewModelInstanceBooleans.

RiveWidgetController? controller;
ViewModelInstance? mainVmi;

@override
  void initState() {
    super.initState();
    // Load rive file
    rootBundle.load('assets/rive/file.riv').then(
      (data) async {
        // Load the RiveFile from the binary data.
        final bytes = data.buffer.asUint8List();

        // Decode into the new File class (choose renderer: rive or flutter)
        final file = await File.decode(
          bytes,
          riveFactory:
              Factory.rive,
        );

        if (file == null) return;

        // Create a controller
        controller = RiveWidgetController(file);
        // Create VMI
        mainVmi = controller!.dataBind(DataBind.auto());

        // Lamp
        lampLightBool = mainVmi!.boolean("LightBoolean")!;
        lampLightBool.value = true;

        // Snow
        snowingBool = mainVmi!.boolean("SnowBoolean")!;
        snowingBool.value = true;
      },
    );
  }

Environment

flutter / dart
rive 0.14.0 (major breaking changes)

What I observe and what I have tried so far

  • The Lamp state machine works just fine. The light is turned on correctly. That's because it's the default state machine.
  • Even though the SnowBoolean is set to true, the animation is never shown.
  • DataBind.auto() loads all boolean properties from the view model.
  • A controller can only control one state machine at a time. And by default that's the default state machine, in my case the Lamp state machine. But I haven't figured out how to switch to a different state machine using a single controller. When setting the controller to the Snow state machine, the snow animation works but the lamp animation no longer does.
  • Creating multiple controllers doesn't work because the RiveWidget only takes one controller parameter and when the second controller is not passed into the RiveWidget it's animation is not shown.
controller = RiveWidgetController(file, stateMachineSelector: StateMachineSelector.byName("Snow"));

My workaround

Splitting the rive file into smaller rive files, each containing only a single state machine.

What am I missing? Is it possible to handle multiple state machines in a single rive file? Thank you for your help!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions