From d38d87f0a3e7031da70b53b8b3874d567465b871 Mon Sep 17 00:00:00 2001 From: teatov Date: Tue, 22 Oct 2024 10:46:20 +1000 Subject: [PATCH] replace animation state machines with blend trees --- .../units/abstract/controlled_ant_unit.tscn | 75 +++++++++++-------- scenes/units/aphid.tscn | 56 +++++++------- scripts/units/abstract/unit.gd | 5 +- scripts/units/aphid.gd | 4 +- scripts/units/components/gathering.gd | 8 +- 5 files changed, 84 insertions(+), 64 deletions(-) diff --git a/scenes/units/abstract/controlled_ant_unit.tscn b/scenes/units/abstract/controlled_ant_unit.tscn index 84a64dd..bf40f8d 100644 --- a/scenes/units/abstract/controlled_ant_unit.tscn +++ b/scenes/units/abstract/controlled_ant_unit.tscn @@ -1,48 +1,50 @@ -[gd_scene load_steps=15 format=3 uid="uid://lbs0vilymbum"] +[gd_scene load_steps=14 format=3 uid="uid://lbs0vilymbum"] [ext_resource type="PackedScene" uid="uid://cidd3q2tet7ku" path="res://scenes/units/abstract/controlled_unit.tscn" id="1_66kao"] [ext_resource type="Script" path="res://scripts/units/abstract/controlled_ant_unit.gd" id="2_77pj2"] [ext_resource type="PackedScene" uid="uid://bi231xk2sp410" path="res://assets/models/ant.glb" id="2_e21vo"] [ext_resource type="AudioStream" uid="uid://ds7c5gkf1mssj" path="res://assets/audio/units/ant_move.wav" id="4_80pw8"] -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_jem3o"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_lip5d"] animation = &"idle" -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_f5jro"] -animation = &"walk" +[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_7c5f2"] -[sub_resource type="AnimationNodeBlendSpace1D" id="AnimationNodeBlendSpace1D_0mwos"] -blend_point_0/node = SubResource("AnimationNodeAnimation_jem3o") -blend_point_0/pos = 0.0 -blend_point_1/node = SubResource("AnimationNodeAnimation_f5jro") -blend_point_1/pos = 1.0 -min_space = 0.0 - -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_gnejs"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_0h55w"] animation = &"plop_down" -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_finoi"] +[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_wsc5y"] +filter_enabled = true +filters = ["Armature/Skeleton3D:Body", "Armature/Skeleton3D:Leg_back_mid_L", "Armature/Skeleton3D:Leg_back_mid_R", "Armature/Skeleton3D:Leg_back_root_L", "Armature/Skeleton3D:Leg_back_root_R", "Armature/Skeleton3D:Leg_back_tip_L", "Armature/Skeleton3D:Leg_back_tip_R", "Armature/Skeleton3D:Leg_front_mid_L", "Armature/Skeleton3D:Leg_front_mid_R", "Armature/Skeleton3D:Leg_front_root_L", "Armature/Skeleton3D:Leg_front_root_R", "Armature/Skeleton3D:Leg_front_tip_L", "Armature/Skeleton3D:Leg_front_tip_R", "Armature/Skeleton3D:Leg_mid_mid_L", "Armature/Skeleton3D:Leg_mid_mid_R", "Armature/Skeleton3D:Leg_mid_root_L", "Armature/Skeleton3D:Leg_mid_root_R", "Armature/Skeleton3D:Leg_mid_tip_L", "Armature/Skeleton3D:Leg_mid_tip_R"] + +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_3qepx"] animation = &"plop_up" -[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_pwnkm"] -advance_mode = 2 +[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_4ftkg"] +filter_enabled = true +filters = ["Armature/Skeleton3D:Body", "Armature/Skeleton3D:Leg_back_mid_L", "Armature/Skeleton3D:Leg_back_mid_R", "Armature/Skeleton3D:Leg_back_root_L", "Armature/Skeleton3D:Leg_back_root_R", "Armature/Skeleton3D:Leg_back_tip_L", "Armature/Skeleton3D:Leg_back_tip_R", "Armature/Skeleton3D:Leg_front_mid_L", "Armature/Skeleton3D:Leg_front_mid_R", "Armature/Skeleton3D:Leg_front_root_L", "Armature/Skeleton3D:Leg_front_root_R", "Armature/Skeleton3D:Leg_front_tip_L", "Armature/Skeleton3D:Leg_front_tip_R", "Armature/Skeleton3D:Leg_mid_mid_L", "Armature/Skeleton3D:Leg_mid_mid_R", "Armature/Skeleton3D:Leg_mid_root_L", "Armature/Skeleton3D:Leg_mid_root_R", "Armature/Skeleton3D:Leg_mid_tip_L", "Armature/Skeleton3D:Leg_mid_tip_R"] -[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_67qgu"] -switch_mode = 2 -advance_mode = 2 +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_grmq1"] +animation = &"walk" -[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_b5tcb"] -switch_mode = 2 -advance_mode = 2 - -[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_v8drs"] -states/locomotion/node = SubResource("AnimationNodeBlendSpace1D_0mwos") -states/locomotion/position = Vector2(334, 100) -states/plop_down/node = SubResource("AnimationNodeAnimation_gnejs") -states/plop_down/position = Vector2(457, 39) -states/plop_up/node = SubResource("AnimationNodeAnimation_finoi") -states/plop_up/position = Vector2(499, 90) -transitions = ["Start", "locomotion", SubResource("AnimationNodeStateMachineTransition_pwnkm"), "plop_down", "locomotion", SubResource("AnimationNodeStateMachineTransition_67qgu"), "plop_up", "locomotion", SubResource("AnimationNodeStateMachineTransition_b5tcb")] +[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_4gyt5"] +graph_offset = Vector2(-327.784, 80.2142) +nodes/idle_anim/node = SubResource("AnimationNodeAnimation_lip5d") +nodes/idle_anim/position = Vector2(-320, 80) +nodes/locomotion_blend/node = SubResource("AnimationNodeBlend2_7c5f2") +nodes/locomotion_blend/position = Vector2(-100, 120) +nodes/output/position = Vector2(680, 160) +nodes/plop_down_anim/node = SubResource("AnimationNodeAnimation_0h55w") +nodes/plop_down_anim/position = Vector2(-40, 360) +nodes/plop_down_oneshot/node = SubResource("AnimationNodeOneShot_wsc5y") +nodes/plop_down_oneshot/position = Vector2(180, 140) +nodes/plop_up_anim/node = SubResource("AnimationNodeAnimation_3qepx") +nodes/plop_up_anim/position = Vector2(260, 400) +nodes/plop_up_oneshot/node = SubResource("AnimationNodeOneShot_4ftkg") +nodes/plop_up_oneshot/position = Vector2(440, 140) +nodes/walk_anim/node = SubResource("AnimationNodeAnimation_grmq1") +nodes/walk_anim/position = Vector2(-320, 220) +node_connections = [&"locomotion_blend", 0, &"idle_anim", &"locomotion_blend", 1, &"walk_anim", &"output", 0, &"plop_up_oneshot", &"plop_down_oneshot", 0, &"locomotion_blend", &"plop_down_oneshot", 1, &"plop_down_anim", &"plop_up_oneshot", 0, &"plop_down_oneshot", &"plop_up_oneshot", 1, &"plop_up_anim"] [sub_resource type="CylinderShape3D" id="CylinderShape3D_8admi"] height = 0.5 @@ -96,11 +98,20 @@ visible = false [node name="NitwitMesh" parent="AntModel/Armature/Skeleton3D" index="1"] visible = false +[node name="AnimationPlayer" parent="AntModel" index="1"] +deterministic = true + [node name="AnimationTree" parent="." index="1"] root_node = NodePath("../AntModel") -tree_root = SubResource("AnimationNodeStateMachine_v8drs") +tree_root = SubResource("AnimationNodeBlendTree_4gyt5") anim_player = NodePath("../AntModel/AnimationPlayer") -parameters/locomotion/blend_position = 0.023431 +parameters/locomotion_blend/blend_amount = 0 +parameters/plop_down_oneshot/active = false +parameters/plop_down_oneshot/internal_active = false +parameters/plop_down_oneshot/request = 0 +parameters/plop_up_oneshot/active = false +parameters/plop_up_oneshot/internal_active = false +parameters/plop_up_oneshot/request = 0 [node name="CollisionShape3D" parent="." index="2"] shape = SubResource("CylinderShape3D_8admi") diff --git a/scenes/units/aphid.tscn b/scenes/units/aphid.tscn index 2d710e6..13750c2 100644 --- a/scenes/units/aphid.tscn +++ b/scenes/units/aphid.tscn @@ -1,39 +1,39 @@ -[gd_scene load_steps=13 format=3 uid="uid://bw8cabkva3k4f"] +[gd_scene load_steps=12 format=3 uid="uid://bw8cabkva3k4f"] [ext_resource type="PackedScene" uid="uid://c70vx0utm5knp" path="res://scenes/units/abstract/unit.tscn" id="1_ghhpv"] [ext_resource type="Script" path="res://scripts/units/aphid.gd" id="2_c6sy4"] [ext_resource type="PackedScene" uid="uid://ch02ae8fj2lhh" path="res://assets/models/aphid.glb" id="2_vtmi4"] [ext_resource type="AudioStream" uid="uid://bqt1xdorarhoi" path="res://assets/audio/units/aphid_move.wav" id="5_f4mon"] -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_f1f0e"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_vr4bn"] animation = &"idle" -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_mfl87"] -animation = &"walk" +[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_6hdai"] -[sub_resource type="AnimationNodeBlendSpace1D" id="AnimationNodeBlendSpace1D_lgt8u"] -blend_point_0/node = SubResource("AnimationNodeAnimation_f1f0e") -blend_point_0/pos = 0.0 -blend_point_1/node = SubResource("AnimationNodeAnimation_mfl87") -blend_point_1/pos = 1.0 -min_space = 0.0 - -[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_vx1kl"] +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_la1j2"] animation = &"plop" -[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_17r08"] -advance_mode = 2 +[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_qspit"] +filter_enabled = true +filters = ["Armature/Skeleton3D:Root"] -[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_vqilr"] -switch_mode = 2 -advance_mode = 2 +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_g6qll"] +animation = &"walk" -[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_38sa4"] -states/locomotion/node = SubResource("AnimationNodeBlendSpace1D_lgt8u") -states/locomotion/position = Vector2(333, 100) -states/plop/node = SubResource("AnimationNodeAnimation_vx1kl") -states/plop/position = Vector2(468, 47) -transitions = ["Start", "locomotion", SubResource("AnimationNodeStateMachineTransition_17r08"), "plop", "locomotion", SubResource("AnimationNodeStateMachineTransition_vqilr")] +[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_a3xja"] +graph_offset = Vector2(-418.868, 27.0018) +nodes/idle_anim/node = SubResource("AnimationNodeAnimation_vr4bn") +nodes/idle_anim/position = Vector2(-180, 100) +nodes/locomotion_blend/node = SubResource("AnimationNodeBlend2_6hdai") +nodes/locomotion_blend/position = Vector2(20, 140) +nodes/output/position = Vector2(500, 160) +nodes/plop_anim/node = SubResource("AnimationNodeAnimation_la1j2") +nodes/plop_anim/position = Vector2(100, 380) +nodes/plop_oneshot/node = SubResource("AnimationNodeOneShot_qspit") +nodes/plop_oneshot/position = Vector2(300, 220) +nodes/walk_anim/node = SubResource("AnimationNodeAnimation_g6qll") +nodes/walk_anim/position = Vector2(-180, 260) +node_connections = [&"locomotion_blend", 0, &"idle_anim", &"locomotion_blend", 1, &"walk_anim", &"output", 0, &"plop_oneshot", &"plop_oneshot", 0, &"locomotion_blend", &"plop_oneshot", 1, &"plop_anim"] [sub_resource type="SphereShape3D" id="SphereShape3D_t1vrx"] radius = 0.3 @@ -55,11 +55,17 @@ bones/13/rotation = Quaternion(-0.235443, -0.235445, 0.666758, 0.666758) bones/14/rotation = Quaternion(-0.235443, -0.235445, 0.666758, 0.666758) bones/15/scale = Vector3(1, 1, 1) +[node name="AnimationPlayer" parent="AphidModel" index="1"] +deterministic = true + [node name="AnimationTree" parent="." index="1"] root_node = NodePath("../AphidModel") -tree_root = SubResource("AnimationNodeStateMachine_38sa4") +tree_root = SubResource("AnimationNodeBlendTree_a3xja") anim_player = NodePath("../AphidModel/AnimationPlayer") -parameters/locomotion/blend_position = 0 +parameters/locomotion_blend/blend_amount = 0.0 +parameters/plop_oneshot/active = false +parameters/plop_oneshot/internal_active = false +parameters/plop_oneshot/request = 0 [node name="CollisionShape3D" parent="." index="2"] shape = SubResource("SphereShape3D_t1vrx") diff --git a/scripts/units/abstract/unit.gd b/scripts/units/abstract/unit.gd index 93ecde7..c124eda 100644 --- a/scripts/units/abstract/unit.gd +++ b/scripts/units/abstract/unit.gd @@ -24,9 +24,6 @@ var _advance_anim_delta_accum: float = 0 @onready var nav_agent: NavigationAgent3D = $NavigationAgent3D @onready var ui_origin: Node3D = $UiOrigin @onready var animation_tree: AnimationTree = $AnimationTree -@onready var animation_playback: AnimationNodeStateMachinePlayback = ( - animation_tree.get("parameters/playback") -) @onready var anim_advance_indicator: VisualInstance3D = $AnimAdvanceIndicator @onready var visibility_notifier: VisibleOnScreenNotifier3D = ( $VisibleOnScreenNotifier3D @@ -116,7 +113,7 @@ func _handle_animation(delta: float) -> void: velocity.length() / _move_speed, delta * LOCOMOTION_CHANGE_SPEED ) - animation_tree.set("parameters/locomotion/blend_position", _locomotion_value) + animation_tree["parameters/locomotion_blend/blend_amount"] = _locomotion_value _advance_anim_delta_accum += delta diff --git a/scripts/units/aphid.gd b/scripts/units/aphid.gd index 648012c..17b8819 100644 --- a/scripts/units/aphid.gd +++ b/scripts/units/aphid.gd @@ -88,7 +88,9 @@ func _handle_honeydew_spawn(delta: float) -> void: _put_honeydew(new_honeydew) audio_player.play_sound(SoundManager.aphid_poop()) - animation_playback.travel("plop") + animation_tree["parameters/plop_oneshot/request"] = ( + AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE + ) _set_spawn_timer() diff --git a/scripts/units/components/gathering.gd b/scripts/units/components/gathering.gd index 3f1d470..ef0b697 100644 --- a/scripts/units/components/gathering.gd +++ b/scripts/units/components/gathering.gd @@ -146,7 +146,9 @@ func _pick_up() -> void: _get_nth_pile_pos(_carrying_items.size() - 1) ).tween_finished audio_player.play_sound(SoundManager.pop()) - _unit.animation_playback.travel("plop_down") + _unit.animation_tree["parameters/plop_down_oneshot/request"] = ( + AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE + ) await get_tree().create_timer(_pickup_interval).timeout @@ -171,7 +173,9 @@ func _deposit() -> void: return var item := _carrying_items.pop_back() as Honeydew - _unit.animation_playback.travel("plop_up") + _unit.animation_tree["parameters/plop_up_oneshot/request"] = ( + AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE + ) audio_player.play_sound(SoundManager.swoosh()) await item.start_tweening(