|
|
|
 |
Reply From: |
Yaann |
Okay, I’ve figured it on my own, it’s pretty long to explain for my end but here’s at least how you switch from the root state machine to a sub-state machine (it’s on C# but it shouldn’t be that hard to convert it to GDScript).
playback = (AnimationNodeStateMachinePlayback) GetNode<AnimationTree>("AnimationTree").Get("parameters/playback");
playback.Start(sub_machine_state);
playback = (AnimationNodeStateMachinePlayback) GetNode<AnimationTree>("AnimationTree").Get("parameters/sub_machine_state/playback");
playback.Start("idle");
However I don’t know if I’m going to keep it like that, there’s plenty of FSM plugins in the Assetlib that probably do the work without the hassle.
1 Like
I hate necroing an old thread but I stumbled upon this when having a similar issue so figured I’d leave a note for people in the future.
Gdscript with Godot version 4.2.1
Animation Tree with BlendSpace2Ds and a StateMachine(attack)
attack has BlendSpace2Ds, one for each weapon type
Screenshots of animation tree below code etc
In my player script I have a match
to switch between MOVE
state and ATTACK
state which are from a local enum
At the top of my player.gd I have this:
@onready var animation_tree:AnimationTree = $PlayerAnimationTree
@onready var animation_state_root:AnimationNodeStateMachinePlayback = $PlayerAnimationTree.get("parameters/playback")
@onready var animation_state_attack:AnimationNodeStateMachinePlayback = $PlayerAnimationTree.get("parameters/attack/playback")
In _physics_process()
I have the following for blend space params:
if normalizedVector != Vector2.ZERO:
animation_tree.set("parameters/idle/blend_position", normalizedVector)
animation_tree.set("parameters/walk/blend_position", normalizedVector)
animation_tree.set("parameters/run/blend_position", normalizedVector)
animation_tree.set('parameters/attack/{weapon}/blend_position'.format({"weapon": player_globals.current_weapon.name}), normalizedVector)
When the player triggers an attack the following code is run:
# travel to attack(state machine)
animation_state_root.travel("attack")
# travel to correct BlendSpace2D inside the nested state machine
animation_state_attack.travel(player_globals.current_weapon.name)
player_globals.current_speed = 0.0
set_velocity(Vector2.ZERO)
# easy way to wait for attack animation to finish before moving on
await animation_tree.animation_finished
state = MOVE
And here are some screenshots for reference: