Rive animation in flutter with nested artboards.
I am trying to figure out the code for a rive animation with nested artboards. I made sure this is the path:
Inspecting Rive File: assets/rsvp3.riv
Root Artboard: Artboard
Nested Artboard: notgoingartboard
Animations: State Machine: notstate
Input Path: notgoingartboard -> notgoing_click (SMITrigger)
Input Path: notgoingartboard -> notgoing_turnoff (SMITrigger)
Nested Artboard: maybeartboard
Animations: State Machine: maybestate
Input Path: maybeartboard -> maybe_click (SMITrigger)
Input Path: maybeartboard -> maybe_turnoff (SMITrigger)
Nested Artboard: goingartboard
Animations: Animation: going
Input Path: goingartboard -> going_click (SMITrigger)
Input Path: goingartboard -> going_turnoff (SMITrigger)
this is how the rive looks like:
I can't figure out the code to show the nested artboards and for it to work.
By default the nested artboard names aren't exported for use at runtime. We do that to reduce the size of the .riv. If you need access to a nested artboard, go to the hierarchy in the parent artboard, right click the nested artboard and select Export Name. Notice that when you do that, the name changes from notgoingartboard
to [notgoingartboard]
. This should fix your problem.
Side note, sorry that the process for testing nested inputs is so tricky. We have a new system coming soon that's going to make it a lot easier.
Hi I did this and it does not solve my issue. Do you have the code that I can use for flutter? I did this but it does not work:
import 'package:flutter/material.dart'; import 'package:rive/rive.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: RiveButtonDemo(), ); } } class RiveButtonDemo extends StatefulWidget { @override _RiveButtonDemoState createState() => _RiveButtonDemoState(); } class _RiveButtonDemoState extends State<RiveButtonDemo> { SMIInput<bool>? notGoingClick; SMIInput<bool>? notGoingTurnOff; SMIInput<bool>? maybeClick; SMIInput<bool>? maybeTurnOff; SMIInput<bool>? goingClick; SMIInput<bool>? goingTurnOff; Artboard? rootArtboard; @override void initState() { super.initState(); loadRiveFile(); } Future<void> loadRiveFile() async { final riveFile = await RiveFile.asset('assets/rsvp3.riv'); // Load Root Artboard rootArtboard = riveFile.artboardByName('Artboard'); if (rootArtboard == null) { print('Root Artboard not found'); return; } // Access Nested Artboards with their State Machines setupArtboardTriggers(riveFile, 'notgoingartboard', 'notstate', (inputMap) { notGoingClick = inputMap['notgoing_click'] as SMIInput<bool>?; notGoingTurnOff = inputMap['notgoing_turnoff'] as SMIInput<bool>?; }); setupArtboardTriggers(riveFile, 'maybeartboard', 'maybestate', (inputMap) { maybeClick = inputMap['maybe_click'] as SMIInput<bool>?; maybeTurnOff = inputMap['maybe_turnoff'] as SMIInput<bool>?; }); setupArtboardTriggers(riveFile, 'goingartboard', 'going', (inputMap) { goingClick = inputMap['going_click'] as SMIInput<bool>?; goingTurnOff = inputMap['going_turnoff'] as SMIInput<bool>?; }); setState(() {}); } void setupArtboardTriggers( RiveFile riveFile, String artboardName, String stateMachineName, Function(Map<String, SMIInput>) setupInputs) { final artboard = riveFile.artboardByName(artboardName); if (artboard != null) { final stateMachineController = StateMachineController.fromArtboard(artboard, stateMachineName); if (stateMachineController != null) { artboard.addController(stateMachineController); final inputs = {for (var input in stateMachineController.inputs) input.name: input}; setupInputs(inputs); } else { print('StateMachineController not found for $artboardName with state machine $stateMachineName'); } } else { print('Artboard $artboardName not found!'); } } void toggleInput(SMIInput<bool>? input) { if (input != null) { input.value = !input.value; // Toggle the boolean value } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Rive Button Demo')), body: Center( child: rootArtboard == null ? CircularProgressIndicator() : Rive( artboard: rootArtboard!, fit: BoxFit.contain, ), ), ); } }
Can you try using the getNumberInput
method? Here are the docs for using inputs on nested artboards: https://rive.app/community/doc/rive-parameters/docHI9ASztXP
final volumeInput = artboard.getNumberInput('notgoing_click', 'notgoingartboard')!; volumeInput.fire()