feat: Implement Phase 16 - Move To: Walk and Run

- Introduced a new action type `move_to` allowing children to direct a stickman to a destination using either Walk or Run styles.
- Updated the ActionEditor UI to include Walk/Run buttons for selecting movement styles.
- Ensured compatibility with existing `walk_to` actions by converting them to the new `move_to` format during loading.
- Defined clear success criteria for the implementation, including distinct movement animations and behavior for both Walk and Run.
- Established a comprehensive verification contract to ensure functionality across various terrains and scenarios.
This commit is contained in:
2026-10-05 15:04:09 -04:00
parent 36596b2c28
commit 3f66cc3195
19 changed files with 2088 additions and 194 deletions
@@ -73,6 +73,94 @@ modifications/4 = SubResource("SkeletonModification2DLookAt_j4hao")
[sub_resource type="Animation" id="Animation_2leu7"]
length = 0.001
[sub_resource type="Animation" id="Animation_RunRight"]
length = 0.75
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("IK_Targets/Torso:position")
tracks/0/interp = 2
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1875, 0.375, 0.5625, 0.75),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"update": 0,
"values": [Vector2(0, 15), Vector2(0, -30), Vector2(0, 15), Vector2(0, -30), Vector2(0, 15)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("IK_Targets/Head:position")
tracks/1/interp = 2
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.1875, 0.375, 0.5625, 0.75),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"update": 0,
"values": [Vector2(100, -605), Vector2(100, -642), Vector2(100, -605), Vector2(100, -642), Vector2(100, -605)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("AnimationTargets/Right_Leg_Base:position")
tracks/2/interp = 2
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.1875, 0.375, 0.5625, 0.75),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"update": 0,
"values": [Vector2(80, 390), Vector2(-120, 290), Vector2(-80, 260), Vector2(110, 240), Vector2(80, 390)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("AnimationTargets/Left_Leg_Base:position")
tracks/3/interp = 2
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.1875, 0.375, 0.5625, 0.75),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"update": 0,
"values": [Vector2(-80, 260), Vector2(110, 240), Vector2(80, 390), Vector2(-120, 290), Vector2(-80, 260)]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("IK_Targets/Right_Hand:position")
tracks/4/interp = 2
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0, 0.09375, 0.1875, 0.28125, 0.375, 0.46875, 0.5625, 0.65625, 0.75),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Vector2(-250, -205), Vector2(-167, -40), Vector2(35, 0), Vector2(237, -40), Vector2(320, -225), Vector2(237, -35), Vector2(35, 15), Vector2(-167, -35), Vector2(-250, -205)]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("IK_Targets/Left_Hand:position")
tracks/5/interp = 2
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0, 0.09375, 0.1875, 0.28125, 0.375, 0.46875, 0.5625, 0.65625, 0.75),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Vector2(320, -225), Vector2(237, -30), Vector2(55, 15), Vector2(-167, -35), Vector2(-250, -205), Vector2(-167, -40), Vector2(55, 0), Vector2(237, -40), Vector2(320, -225)]
}
tracks/6/type = "value"
tracks/6/imported = false
tracks/6/enabled = true
tracks/6/path = NodePath("IK_Targets/Torso:rotation")
tracks/6/interp = 2
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(0, 0.1875, 0.375, 0.5625, 0.75),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"update": 0,
"values": [0.3, 0.36, 0.28, 0.2, 0.3]
}
[sub_resource type="Animation" id="Animation_ylko5"]
length = 0.8
tracks/0/type = "value"
@@ -315,6 +403,7 @@ tracks/5/keys = {
[sub_resource type="AnimationLibrary" id="AnimationLibrary_t75yq"]
_data = {
&"RESET": SubResource("Animation_2leu7"),
&"run_right": SubResource("Animation_RunRight"),
&"stand_up": SubResource("Animation_ylko5"),
&"walk_left": SubResource("Animation_t75yq"),
&"walk_right": SubResource("Animation_m3sq4")