let linear_animation =LinearAnimation { riv: asset_server.load("marty.riv"),// Optionally provide animation name to load handle: rive_bevy::Handle::Name("Animation1".into()),// Optionally provide artboard name to load artboard_handle: rive_bevy::Handle::Name("New Artboard".into()),..default()};
StateMachine:
let state_machine =StateMachine { riv: asset_server.load("marty.riv"),// Optionally provide State Machine name to load handle: rive_bevy::Handle::Name("State Machine 1".into()),// Optionally provide artboard name to load artboard_handle: rive_bevy::Handle::Name("New Artboard".into()),..default()};
The following example demonstrates drawing a StateMachine to a SpriteBundle in a 2D scene and enables user interaction via a mouse to drive Rive Listeners.
use bevy::{prelude::*, render::render_resource::Extent3d, window};use rive_bevy::{RivePlugin, SceneTarget, SpriteEntity, StateMachine};fnmain() {App::new().add_plugins(DefaultPlugins).add_plugins(RivePlugin).add_systems(Startup, setup_animation).add_systems(Update, window::close_on_esc).run()}fnsetup_animation(mut commands:Commands,mut images:ResMut<Assets<Image>>, asset_server:Res<AssetServer>,) {letmut animation_image =Image::default();// We fill the CPU image with 0s before sending it to the GPU. animation_image.resize(Extent3d { width:512, height:512,..default() });let animation_image_handle = images.add(animation_image.clone()); commands.spawn(Camera2dBundle { ..default() });let sprite_entity = commands.spawn(SpriteBundle { texture: animation_image_handle.clone(), transform: Transform::from_scale(Vec3::splat(1.0)),..default() }).id();let state_machine =StateMachine { riv: asset_server.load("rating-animation.riv"),// Optionally provide state machine name to load handle: rive_bevy::Handle::Name("State Machine 1".into()),// Optionally provide artboard name to load artboard_handle: rive_bevy::Handle::Name("New Artboard".into()),..default() }; commands.spawn(state_machine).insert(SceneTarget { image: animation_image_handle,// Adding the sprite here enables mouse input being passed to the Scene. sprite:SpriteEntity { entity:Some(sprite_entity), },..default() });}
Create a new Image and resize it to be the same aspect ratio as your Rive artboard. Note that an Artboard my have clipping disabled and elements could be drawn outside of the bounds. In that case you'd want to size the Image to take up the drawable area.
Spawn a new SpriteBundle providing the image as a texture.
Create a StateMachine, optionally provide the handle (state machine name) and artboard_handle (artboard name).
Spawn a new SceneTarget, optionally provide the sprite argument which enables mouse inputs to pass to the scene. This is only relevant for State Machine animations as Linear Animations cannot interact with Rive listeners.
3D Scene
The following demonstrates drawing a StateMachine to a StandardMaterial in a 3D scene and enables user interaction via a mouse to drive Rive Listeners.
use bevy::{prelude::*, render::render_resource::Extent3d, window};use rive_bevy::{RivePlugin, SceneTarget, StateMachine};fnmain() {App::new().add_plugins(DefaultPlugins).add_plugins(RivePlugin).add_systems(Startup, setup_animation).add_systems(Update, rotate_cube).add_systems(Update, window::close_on_esc).run()}#[derive(Component)]structDefaultCube;fnsetup_animation(mut commands:Commands,mut images:ResMut<Assets<Image>>,mut meshes:ResMut<Assets<Mesh>>,mut materials:ResMut<Assets<StandardMaterial>>, asset_server:Res<AssetServer>,) {letmut animation_image =Image::default();// We fill the CPU image with 0s before sending it to the GPU. animation_image.resize(Extent3d { width:512, height:512,..default() });let animation_image_handle = images.add(animation_image.clone());let cube_size =4.0;let cube_handle = meshes.add(Mesh::from(shape::Box::new(cube_size, cube_size, cube_size)));let material_handle = materials.add(StandardMaterial { base_color_texture:Some(animation_image_handle.clone()), reflectance:0.02, unlit:false,..default() });let cube_entity = commands.spawn((PbrBundle { mesh: cube_handle, material: material_handle, transform: Transform::from_xyz(0.0, 0.0, 1.5),..default() },DefaultCube, )).id(); commands.spawn(PointLightBundle { point_light:PointLight { intensity:3000.0,..default() },// Light in front of the 3D camera. transform: Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)),..default() }); commands.spawn(Camera3dBundle { transform: Transform::from_xyz(0.0, 0.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y),..default() });let linear_animation =StateMachine { riv: asset_server.load("rating-animation.riv"),// Optionally provide state machine name to load handle: rive_bevy::Handle::Name("State Machine 1".into()),// Optionally provide artboard name to load artboard_handle: rive_bevy::Handle::Name("New Artboard".into()),..default() }; commands.spawn(linear_animation).insert(SceneTarget { image: animation_image_handle,// Adding the sprite here enables mouse input being passed to the Scene. mesh: rive_bevy::MeshEntity { entity:Some(cube_entity), },..default() });}fnrotate_cube(time:Res<Time>, mut query:Query<&mutTransform, With<DefaultCube>>) {formut transform in&mut query { transform.rotate_x(0.6* time.delta_seconds()); transform.rotate_y(-0.2* time.delta_seconds()); }}