1
+ use fyrox:: animation:: machine:: MachineLayer ;
2
+ use fyrox:: scene:: animation:: { AnimationPlayer , AnimationPlayerBuilder } ;
1
3
use fyrox:: {
2
4
animation:: {
3
5
machine:: { Machine , Parameter , PoseNode , State , Transition } ,
@@ -37,7 +39,7 @@ impl Bot {
37
39
. request_model ( "data/models/zombie.fbx" )
38
40
. await
39
41
. unwrap ( )
40
- . instantiate_geometry ( scene) ;
42
+ . instantiate ( scene) ;
41
43
42
44
scene. graph [ model]
43
45
. local_transform_mut ( )
@@ -130,20 +132,20 @@ impl Bot {
130
132
fn create_play_animation_state (
131
133
animation_resource : Model ,
132
134
name : & str ,
133
- machine : & mut Machine ,
135
+ layer : & mut MachineLayer ,
134
136
scene : & mut Scene ,
135
137
model : Handle < Node > ,
136
138
) -> ( Handle < Animation > , Handle < State > ) {
137
139
// Animations retargetting just makes an instance of animation and binds it to
138
140
// given model using names of bones.
139
141
let animation = * animation_resource
140
- . retarget_animations ( model, scene)
142
+ . retarget_animations ( model, & mut scene. graph )
141
143
. get ( 0 )
142
144
. unwrap ( ) ;
143
145
// Create new PlayAnimation node and add it to machine.
144
- let node = machine . add_node ( PoseNode :: make_play_animation ( animation) ) ;
146
+ let node = layer . add_node ( PoseNode :: make_play_animation ( animation) ) ;
145
147
// Make a state using the node we've made.
146
- let state = machine . add_state ( State :: new ( name, node) ) ;
148
+ let state = layer . add_state ( State :: new ( name, node) ) ;
147
149
( animation, state)
148
150
}
149
151
@@ -155,6 +157,7 @@ pub struct BotAnimationMachineInput {
155
157
}
156
158
157
159
pub struct BotAnimationMachine {
160
+ animation_player : Handle < Node > ,
158
161
machine : Machine ,
159
162
}
160
163
@@ -172,7 +175,13 @@ impl BotAnimationMachine {
172
175
model : Handle < Node > ,
173
176
resource_manager : ResourceManager ,
174
177
) -> Self {
175
- let mut machine = Machine :: new ( model) ;
178
+ let animation_player =
179
+ AnimationPlayerBuilder :: new ( BaseBuilder :: new ( ) ) . build ( & mut scene. graph ) ;
180
+ scene. graph . link_nodes ( animation_player, model) ;
181
+
182
+ let mut machine = Machine :: new ( ) ;
183
+
184
+ let root = machine. layers_mut ( ) . first_mut ( ) . unwrap ( ) ;
176
185
177
186
// Load animations in parallel.
178
187
let ( walk_animation_resource, idle_animation_resource, attack_animation_resource) = fyrox:: core:: futures:: join!(
@@ -185,29 +194,29 @@ impl BotAnimationMachine {
185
194
let ( _, idle_state) = create_play_animation_state (
186
195
idle_animation_resource. unwrap ( ) ,
187
196
"Idle" ,
188
- & mut machine ,
197
+ root ,
189
198
scene,
190
199
model,
191
200
) ;
192
201
193
202
let ( walk_animation, walk_state) = create_play_animation_state (
194
203
walk_animation_resource. unwrap ( ) ,
195
204
"Walk" ,
196
- & mut machine ,
205
+ root ,
197
206
scene,
198
207
model,
199
208
) ;
200
209
201
210
let ( attack_animation, attack_state) = create_play_animation_state (
202
211
attack_animation_resource. unwrap ( ) ,
203
212
"Attack" ,
204
- & mut machine ,
213
+ root ,
205
214
scene,
206
215
model,
207
216
) ;
208
217
209
218
// Next, define transitions between states.
210
- machine . add_transition ( Transition :: new (
219
+ root . add_transition ( Transition :: new (
211
220
// A name for debugging.
212
221
"Idle->Walk" ,
213
222
// Source state.
@@ -219,35 +228,35 @@ impl BotAnimationMachine {
219
228
// A name of transition rule parameter.
220
229
Self :: IDLE_TO_WALK ,
221
230
) ) ;
222
- machine . add_transition ( Transition :: new (
231
+ root . add_transition ( Transition :: new (
223
232
"Walk->Idle" ,
224
233
walk_state,
225
234
idle_state,
226
235
0.4 ,
227
236
Self :: WALK_TO_IDLE ,
228
237
) ) ;
229
- machine . add_transition ( Transition :: new (
238
+ root . add_transition ( Transition :: new (
230
239
"Walk->Attack" ,
231
240
walk_state,
232
241
attack_state,
233
242
0.4 ,
234
243
Self :: WALK_TO_ATTACK ,
235
244
) ) ;
236
- machine . add_transition ( Transition :: new (
245
+ root . add_transition ( Transition :: new (
237
246
"Idle->Attack" ,
238
247
idle_state,
239
248
attack_state,
240
249
0.4 ,
241
250
Self :: IDLE_TO_ATTACK ,
242
251
) ) ;
243
- machine . add_transition ( Transition :: new (
252
+ root . add_transition ( Transition :: new (
244
253
"Attack->Idle" ,
245
254
attack_state,
246
255
idle_state,
247
256
0.4 ,
248
257
Self :: ATTACK_TO_IDLE ,
249
258
) ) ;
250
- machine . add_transition ( Transition :: new (
259
+ root . add_transition ( Transition :: new (
251
260
"Attack->Walk" ,
252
261
attack_state,
253
262
walk_state,
@@ -256,12 +265,19 @@ impl BotAnimationMachine {
256
265
) ) ;
257
266
258
267
// Define entry state.
259
- machine . set_entry_state ( idle_state) ;
268
+ root . set_entry_state ( idle_state) ;
260
269
261
- Self { machine }
270
+ Self {
271
+ animation_player,
272
+ machine,
273
+ }
262
274
}
263
275
264
276
pub fn update ( & mut self , scene : & mut Scene , dt : f32 , input : BotAnimationMachineInput ) {
277
+ let animation_player = scene. graph [ self . animation_player ]
278
+ . query_component_ref :: < AnimationPlayer > ( )
279
+ . unwrap ( ) ;
280
+
265
281
self . machine
266
282
// Set transition parameters.
267
283
. set_parameter ( Self :: WALK_TO_IDLE , Parameter :: Rule ( !input. walk ) )
@@ -271,7 +287,7 @@ impl BotAnimationMachine {
271
287
. set_parameter ( Self :: ATTACK_TO_IDLE , Parameter :: Rule ( !input. attack ) )
272
288
. set_parameter ( Self :: ATTACK_TO_WALK , Parameter :: Rule ( !input. attack ) )
273
289
// Update machine and evaluate final pose.
274
- . evaluate_pose ( & scene . animations , dt)
290
+ . evaluate_pose ( animation_player . animations ( ) , dt)
275
291
// Apply the pose to the graph.
276
292
. apply ( & mut scene. graph ) ;
277
293
}
0 commit comments