feat: added running
parent
95375eae4a
commit
32df02855b
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
godot/models/character.glb (Stored with Git LFS)
BIN
godot/models/character.glb (Stored with Git LFS)
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,38 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://baoj103pows5q"
|
||||
path.s3tc="res://.godot/imported/character_planks.png-bf4e3c43ee8f1eb697542bf0bfee54a6.s3tc.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
generator_parameters={
|
||||
"md5": "9a04a9ca6cb72f21abef3f2804c5e752"
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://models/character_planks.png"
|
||||
dest_files=["res://.godot/imported/character_planks.png-bf4e3c43ee8f1eb697542bf0bfee54a6.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
Binary file not shown.
|
@ -0,0 +1,38 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dufw5fjifcf1k"
|
||||
path.s3tc="res://.godot/imported/character_planks_normal.png-d0077007b1140868b34ce522fc43d375.s3tc.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
generator_parameters={
|
||||
"md5": "6e727784c943200bad88fe614defb855"
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://models/character_planks_normal.png"
|
||||
dest_files=["res://.godot/imported/character_planks_normal.png-d0077007b1140868b34ce522fc43d375.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=1
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=1
|
||||
roughness/src_normal="res://models/character_planks_normal.png"
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
BIN
godot/models/props/trenchwall_2m.glb (Stored with Git LFS)
BIN
godot/models/props/trenchwall_2m.glb (Stored with Git LFS)
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=29 format=3 uid="uid://1kr3qqan3trk"]
|
||||
[gd_scene load_steps=39 format=3 uid="uid://1kr3qqan3trk"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://vub54xgk5n0h" path="res://models/character.glb" id="1_mi4co"]
|
||||
|
||||
|
@ -17,9 +17,33 @@ animation = &"Aim"
|
|||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_8rbkq"]
|
||||
animation = &"Aim_Fire"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ugv1e"]
|
||||
animation = &"RESET"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ds004"]
|
||||
animation = &"RESET"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_axx41"]
|
||||
animation = &"Run_forward"
|
||||
|
||||
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_aunq0"]
|
||||
filter_enabled = true
|
||||
filters = ["skeleton_character/Skeleton3D:Foot.L", "skeleton_character/Skeleton3D:Foot.R", "skeleton_character/Skeleton3D:IKTarget.Foot.L", "skeleton_character/Skeleton3D:IKTarget.Foot.R", "skeleton_character/Skeleton3D:Neck", "skeleton_character/Skeleton3D:PoleTarget.Foot.L", "skeleton_character/Skeleton3D:PoleTarget.Foot.R", "skeleton_character/Skeleton3D:hip", "skeleton_character/Skeleton3D:lowerleg.L", "skeleton_character/Skeleton3D:lowerleg.R", "skeleton_character/Skeleton3D:root", "skeleton_character/Skeleton3D:spine.001", "skeleton_character/Skeleton3D:spine.002", "skeleton_character/Skeleton3D:spine.003", "skeleton_character/Skeleton3D:upperleg.L", "skeleton_character/Skeleton3D:upperleg.R"]
|
||||
|
||||
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_hmklb"]
|
||||
graph_offset = Vector2(-813.273, 105.409)
|
||||
nodes/Rest/node = SubResource("AnimationNodeAnimation_ds004")
|
||||
nodes/Rest/position = Vector2(-160, 160)
|
||||
nodes/Run/node = SubResource("AnimationNodeAnimation_axx41")
|
||||
nodes/Run/position = Vector2(-160, 380)
|
||||
nodes/Speed/node = SubResource("AnimationNodeBlend2_aunq0")
|
||||
nodes/Speed/position = Vector2(80, 140)
|
||||
nodes/output/position = Vector2(320, 140)
|
||||
node_connections = [&"Speed", 0, &"Rest", &"Speed", 1, &"Run", &"output", 0, &"Speed"]
|
||||
|
||||
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_4hmb8"]
|
||||
filter_enabled = true
|
||||
filters = ["Character/Skeleton3D:Foot.L", "Character/Skeleton3D:Foot.R", "Character/Skeleton3D:IKTarget.Foot.L", "Character/Skeleton3D:IKTarget.Foot.R", "Character/Skeleton3D:Neck", "Character/Skeleton3D:PoleTarget.Foot.L", "Character/Skeleton3D:PoleTarget.Foot.R", "Character/Skeleton3D:hip", "Character/Skeleton3D:lowerleg.L", "Character/Skeleton3D:lowerleg.R", "Character/Skeleton3D:root", "Character/Skeleton3D:spine.001", "Character/Skeleton3D:spine.002", "Character/Skeleton3D:spine.003", "Character/Skeleton3D:upperleg.L", "Character/Skeleton3D:upperleg.R"]
|
||||
filters = ["Character/Skeleton3D:Foot.L", "Character/Skeleton3D:Foot.R", "Character/Skeleton3D:IKTarget.Foot.L", "Character/Skeleton3D:IKTarget.Foot.R", "Character/Skeleton3D:Neck", "Character/Skeleton3D:PoleTarget.Foot.L", "Character/Skeleton3D:PoleTarget.Foot.R", "Character/Skeleton3D:hip", "Character/Skeleton3D:lowerleg.L", "Character/Skeleton3D:lowerleg.R", "Character/Skeleton3D:root", "Character/Skeleton3D:spine.003", "Character/Skeleton3D:upperleg.L", "Character/Skeleton3D:upperleg.R"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_5n7ai"]
|
||||
animation = &"RESET"
|
||||
|
@ -42,7 +66,7 @@ blend_point_2/node = SubResource("AnimationNodeAnimation_6neek")
|
|||
blend_point_2/pos = 0.0
|
||||
|
||||
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_p0hk7"]
|
||||
graph_offset = Vector2(-599, 14)
|
||||
graph_offset = Vector2(-480.5, 90)
|
||||
nodes/BoneMask/node = SubResource("AnimationNodeBlend2_4hmb8")
|
||||
nodes/BoneMask/position = Vector2(140, 140)
|
||||
nodes/Rest/node = SubResource("AnimationNodeAnimation_5n7ai")
|
||||
|
@ -57,25 +81,25 @@ animation = &"RESET"
|
|||
|
||||
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_rb1jd"]
|
||||
filter_enabled = true
|
||||
filters = ["Character/Skeleton3D:Foot.L", "Character/Skeleton3D:Foot.R", "Character/Skeleton3D:IKTarget.Foot.L", "Character/Skeleton3D:IKTarget.Foot.R", "Character/Skeleton3D:hip", "Character/Skeleton3D:lowerleg.L", "Character/Skeleton3D:lowerleg.R", "Character/Skeleton3D:root", "Character/Skeleton3D:upperleg.L", "Character/Skeleton3D:upperleg.R"]
|
||||
filters = ["Character/Skeleton3D:Foot.L", "Character/Skeleton3D:Foot.R", "Character/Skeleton3D:IKTarget.Foot.L", "Character/Skeleton3D:IKTarget.Foot.R", "Character/Skeleton3D:hip", "Character/Skeleton3D:lowerleg.L", "Character/Skeleton3D:lowerleg.R", "Character/Skeleton3D:root", "Character/Skeleton3D:upperleg.L", "Character/Skeleton3D:upperleg.R", "skeleton_character/Skeleton3D:Foot.L", "skeleton_character/Skeleton3D:Foot.R", "skeleton_character/Skeleton3D:IKTarget.Foot.L", "skeleton_character/Skeleton3D:IKTarget.Foot.R", "skeleton_character/Skeleton3D:Neck", "skeleton_character/Skeleton3D:PoleTarget.Foot.L", "skeleton_character/Skeleton3D:PoleTarget.Foot.R", "skeleton_character/Skeleton3D:hip", "skeleton_character/Skeleton3D:lowerleg.L", "skeleton_character/Skeleton3D:lowerleg.R", "skeleton_character/Skeleton3D:root", "skeleton_character/Skeleton3D:spine.001", "skeleton_character/Skeleton3D:spine.002", "skeleton_character/Skeleton3D:spine.003", "skeleton_character/Skeleton3D:upperleg.L", "skeleton_character/Skeleton3D:upperleg.R"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_psu0r"]
|
||||
animation = &"Walk_forward"
|
||||
|
||||
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_2mbyh"]
|
||||
graph_offset = Vector2(-703.5, -8.5)
|
||||
graph_offset = Vector2(-724.58, 74.5681)
|
||||
nodes/Base/node = SubResource("AnimationNodeAnimation_7ceai")
|
||||
nodes/Base/position = Vector2(-120, 120)
|
||||
nodes/Forward/node = SubResource("AnimationNodeBlend2_rb1jd")
|
||||
nodes/Forward/position = Vector2(100, 120)
|
||||
nodes/Speed/node = SubResource("AnimationNodeBlend2_rb1jd")
|
||||
nodes/Speed/position = Vector2(100, 120)
|
||||
nodes/Walk/node = SubResource("AnimationNodeAnimation_psu0r")
|
||||
nodes/Walk/position = Vector2(-140, 300)
|
||||
node_connections = [&"Forward", 0, &"Base", &"Forward", 1, &"Walk", &"output", 0, &"Forward"]
|
||||
node_connections = [&"Speed", 0, &"Base", &"Speed", 1, &"Walk", &"output", 0, &"Speed"]
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_4lybd"]
|
||||
switch_mode = 2
|
||||
advance_mode = 2
|
||||
advance_expression = "get_input_directions().y >= -0.9"
|
||||
advance_expression = "!aim_weapon"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_5aafd"]
|
||||
xfade_time = 0.3
|
||||
|
@ -87,7 +111,7 @@ advance_expression = "get_input_direction() > 0.f"
|
|||
priority = 2
|
||||
switch_mode = 2
|
||||
advance_mode = 2
|
||||
advance_expression = "get_input_fire()"
|
||||
advance_expression = "get_fire_weapon()"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_xnat3"]
|
||||
reset = false
|
||||
|
@ -107,39 +131,71 @@ advance_mode = 2
|
|||
xfade_time = 0.2
|
||||
priority = 2
|
||||
advance_mode = 2
|
||||
advance_expression = "get_input_directions().y < 0.5"
|
||||
advance_expression = "!is_walking"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_4hisb"]
|
||||
xfade_time = 0.2
|
||||
advance_mode = 2
|
||||
advance_expression = "get_input_directions().y >= 0.5"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_333v8"]
|
||||
advance_mode = 2
|
||||
advance_expression = "get_input_directions().y < -0.9"
|
||||
advance_expression = "is_walking"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_bmty6"]
|
||||
advance_mode = 2
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_kyd6p"]
|
||||
xfade_time = 0.05
|
||||
advance_mode = 2
|
||||
advance_expression = "aim_weapon"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_w5kob"]
|
||||
switch_mode = 2
|
||||
advance_mode = 2
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_g0i3x"]
|
||||
xfade_time = 0.4
|
||||
advance_mode = 2
|
||||
advance_expression = "get_is_running()
|
||||
"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_ocffv"]
|
||||
xfade_time = 0.3
|
||||
advance_mode = 2
|
||||
advance_expression = "get_is_running()
|
||||
"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_h0my5"]
|
||||
xfade_time = 0.4
|
||||
advance_mode = 2
|
||||
advance_expression = "!get_is_running()"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_nymcr"]
|
||||
xfade_time = 0.3
|
||||
advance_mode = 2
|
||||
advance_expression = "!get_is_running()"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_7smdg"]
|
||||
"states/Aim Down [aim]/node" = SubResource("AnimationNodeAnimation_ukhqm")
|
||||
"states/Aim Down [aim]/position" = Vector2(706.171, 191.767)
|
||||
"states/Aim Down [aim]/position" = Vector2(666.26, 226.767)
|
||||
"states/Aim [aim] [turn]/node" = SubResource("AnimationNodeAnimation_nhlru")
|
||||
"states/Aim [aim] [turn]/position" = Vector2(705.26, 88.389)
|
||||
"states/Aim [aim] [turn]/position" = Vector2(731.26, 94.3447)
|
||||
states/End/position = Vector2(195.182, 94.3447)
|
||||
"states/Fire [aim]/node" = SubResource("AnimationNodeAnimation_8rbkq")
|
||||
"states/Fire [aim]/position" = Vector2(706.18, 14.9346)
|
||||
"states/Fire [aim]/position" = Vector2(731.26, 14.954)
|
||||
"states/RESET To Aim/node" = SubResource("AnimationNodeAnimation_ugv1e")
|
||||
"states/RESET To Aim/position" = Vector2(566.993, 94.3447)
|
||||
states/Run/node = SubResource("AnimationNodeBlendTree_hmklb")
|
||||
states/Run/position = Vector2(297.422, 226.767)
|
||||
states/Start/position = Vector2(383.995, 14.954)
|
||||
"states/Stationary [turn]/node" = SubResource("AnimationNodeBlendTree_p0hk7")
|
||||
"states/Stationary [turn]/position" = Vector2(383.995, 94.3447)
|
||||
"states/Walk [turn]/node" = SubResource("AnimationNodeBlendTree_2mbyh")
|
||||
"states/Walk [turn]/position" = Vector2(383.995, 191.767)
|
||||
transitions = ["Aim [aim] [turn]", "Aim Down [aim]", SubResource("AnimationNodeStateMachineTransition_4lybd"), "Aim Down [aim]", "Walk [turn]", SubResource("AnimationNodeStateMachineTransition_5aafd"), "Aim [aim] [turn]", "Fire [aim]", SubResource("AnimationNodeStateMachineTransition_8f4gl"), "Fire [aim]", "Aim [aim] [turn]", SubResource("AnimationNodeStateMachineTransition_xnat3"), "Walk [turn]", "Aim [aim] [turn]", SubResource("AnimationNodeStateMachineTransition_12bos"), "Aim Down [aim]", "Stationary [turn]", SubResource("AnimationNodeStateMachineTransition_n0ndr"), "Walk [turn]", "Stationary [turn]", SubResource("AnimationNodeStateMachineTransition_0wc5e"), "Stationary [turn]", "Walk [turn]", SubResource("AnimationNodeStateMachineTransition_4hisb"), "Stationary [turn]", "Aim [aim] [turn]", SubResource("AnimationNodeStateMachineTransition_333v8"), "Start", "Stationary [turn]", SubResource("AnimationNodeStateMachineTransition_bmty6")]
|
||||
graph_offset = Vector2(-98.007, -6.1553)
|
||||
"states/Walk [turn]/position" = Vector2(477.995, 226.767)
|
||||
transitions = ["Aim [aim] [turn]", "Aim Down [aim]", SubResource("AnimationNodeStateMachineTransition_4lybd"), "Aim Down [aim]", "Walk [turn]", SubResource("AnimationNodeStateMachineTransition_5aafd"), "Aim [aim] [turn]", "Fire [aim]", SubResource("AnimationNodeStateMachineTransition_8f4gl"), "Fire [aim]", "Aim [aim] [turn]", SubResource("AnimationNodeStateMachineTransition_xnat3"), "Walk [turn]", "Aim [aim] [turn]", SubResource("AnimationNodeStateMachineTransition_12bos"), "Aim Down [aim]", "Stationary [turn]", SubResource("AnimationNodeStateMachineTransition_n0ndr"), "Walk [turn]", "Stationary [turn]", SubResource("AnimationNodeStateMachineTransition_0wc5e"), "Stationary [turn]", "Walk [turn]", SubResource("AnimationNodeStateMachineTransition_4hisb"), "Start", "Stationary [turn]", SubResource("AnimationNodeStateMachineTransition_bmty6"), "Stationary [turn]", "RESET To Aim", SubResource("AnimationNodeStateMachineTransition_kyd6p"), "RESET To Aim", "Aim [aim] [turn]", SubResource("AnimationNodeStateMachineTransition_w5kob"), "Stationary [turn]", "Run", SubResource("AnimationNodeStateMachineTransition_g0i3x"), "Walk [turn]", "Run", SubResource("AnimationNodeStateMachineTransition_ocffv"), "Run", "Stationary [turn]", SubResource("AnimationNodeStateMachineTransition_h0my5"), "Run", "Walk [turn]", SubResource("AnimationNodeStateMachineTransition_nymcr")]
|
||||
graph_offset = Vector2(-392.578, -45.655)
|
||||
|
||||
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_hiswf"]
|
||||
graph_offset = Vector2(-155, 2)
|
||||
nodes/Actions/node = SubResource("AnimationNodeStateMachine_7smdg")
|
||||
nodes/Actions/position = Vector2(90.9091, 145.455)
|
||||
nodes/Actions/position = Vector2(80, 140)
|
||||
nodes/output/position = Vector2(327.273, 163.636)
|
||||
node_connections = [&"output", 0, &"Actions"]
|
||||
|
||||
|
@ -149,15 +205,16 @@ radius = 0.370388
|
|||
[node name="Player" type="Player"]
|
||||
slide_on_ceiling = false
|
||||
floor_constant_speed = true
|
||||
safe_margin = 0.005
|
||||
|
||||
[node name="PlayerInput" type="PlayerInput" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="CharacterModel" parent="." instance=ExtResource("1_mi4co")]
|
||||
unique_name_in_owner = true
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0337329, 0)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0232956, 0)
|
||||
|
||||
[node name="Skeleton3D" parent="CharacterModel/Character" index="0"]
|
||||
[node name="Skeleton3D" parent="CharacterModel/skeleton_character" index="0"]
|
||||
bones/0/rotation = Quaternion(1.12928e-22, 1, 2.98023e-08, -1.94707e-07)
|
||||
bones/1/position = Vector3(3.28472e-17, 0.826102, -2.26306e-09)
|
||||
bones/1/rotation = Quaternion(-0.0189874, -6.30661e-09, -1.08732e-09, 0.99982)
|
||||
|
@ -250,16 +307,16 @@ bones/60/rotation = Quaternion(-0.707107, 1.25097e-07, 1.25097e-07, 0.707107)
|
|||
bones/61/rotation = Quaternion(-0.707107, 1.5189e-07, 1.5189e-07, 0.707107)
|
||||
bones/62/rotation = Quaternion(-0.707107, 1.5189e-07, 1.5189e-07, 0.707107)
|
||||
|
||||
[node name="AnimationTree" type="AnimationTree" parent="CharacterModel"]
|
||||
[node name="AnimationTree" type="PlayerAnimTree" parent="CharacterModel"]
|
||||
unique_name_in_owner = true
|
||||
root_node = NodePath("%AnimationTree/..")
|
||||
root_motion_track = NodePath("Character/Skeleton3D:root")
|
||||
root_motion_track = NodePath("skeleton_character/Skeleton3D:root")
|
||||
tree_root = SubResource("AnimationNodeBlendTree_hiswf")
|
||||
advance_expression_base_node = NodePath("../..")
|
||||
anim_player = NodePath("../AnimationPlayer")
|
||||
parameters/Actions/Run/Speed/blend_amount = 1.0
|
||||
"parameters/Actions/Stationary [turn]/BoneMask/blend_amount" = 1.0
|
||||
"parameters/Actions/Stationary [turn]/Turn/blend_position" = 0
|
||||
"parameters/Actions/Walk [turn]/Forward/blend_amount" = 1.0
|
||||
"parameters/Actions/Stationary [turn]/Turn/blend_position" = 0.0
|
||||
"parameters/Actions/Walk [turn]/Speed/blend_amount" = 1.0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||
|
@ -270,7 +327,7 @@ unique_name_in_owner = true
|
|||
top_level = true
|
||||
|
||||
[node name="Camera" type="Camera3D" parent="CameraParent"]
|
||||
transform = Transform3D(-0.999748, 0.00680423, -0.0213691, 0.00384561, 0.990762, 0.135556, 0.0220941, 0.13544, -0.990539, -0.434839, 1.68404, -1.00653)
|
||||
transform = Transform3D(-0.999749, 0.00680422, -0.0213691, 0.00384561, 0.990762, 0.135556, 0.0220941, 0.13544, -0.990539, -0.311477, 1.66006, -1.85354)
|
||||
fov = 42.5804
|
||||
far = 100.0
|
||||
|
||||
|
|
|
@ -76,6 +76,12 @@ fire={
|
|||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":2,"pressure":0.0,"pressed":true,"script":null)
|
||||
]
|
||||
}
|
||||
run={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[physics]
|
||||
|
||||
|
|
BIN
models/character.blend (Stored with Git LFS)
BIN
models/character.blend (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
BIN
models/modules.blend (Stored with Git LFS)
BIN
models/modules.blend (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
|
@ -6,18 +6,17 @@
|
|||
void Player::_bind_methods() {
|
||||
#define CLASSNAME Player
|
||||
GDFUNCTION(get_input_directions);
|
||||
GDFUNCTION(get_input_fire);
|
||||
}
|
||||
|
||||
void Player::_ready() {
|
||||
if(gd::Engine::get_singleton()->is_editor_hint())
|
||||
return;
|
||||
this->anim_tree = this->get_node<gd::AnimationTree>("%AnimationTree");
|
||||
this->fsm = gd::Object::cast_to<gd::AnimationNodeStateMachinePlayback>(this->anim_tree->get("parameters/Actions/playback"));
|
||||
this->anim_tree = this->get_node<PlayerAnimTree>("%AnimationTree");
|
||||
this->input = this->get_node<utils::PlayerInput>("%PlayerInput");
|
||||
this->input->listen_to(utils::PlayerInput::Listener("dir_left", "dir_right", callable_mp(this, &Player::_on_dir_horizontal)));
|
||||
this->input->listen_to(utils::PlayerInput::Listener("dir_backward", "dir_forward", callable_mp(this, &Player::_on_dir_vertical)));
|
||||
this->input->listen_to(utils::PlayerInput::Listener("fire", callable_mp(this, &Player::_on_fire)));
|
||||
this->input->listen_to(utils::PlayerInput::Listener("run", callable_mp(this, &Player::_on_run)));
|
||||
this->model_node = this->get_node<gd::Node3D>("%CharacterModel");
|
||||
this->camera_parent = this->get_node<gd::Node3D>("%CameraParent");
|
||||
this->camera_parent->set_global_rotation(this->get_global_rotation());
|
||||
|
@ -30,41 +29,43 @@ void Player::_process(double delta) {
|
|||
this->input_fire -= delta;
|
||||
this->process_rotate(delta);
|
||||
this->process_transform_camera(delta);
|
||||
}
|
||||
|
||||
void Player::_physics_process(double delta [[maybe_unused]]) {
|
||||
if(gd::Engine::get_singleton()->is_editor_hint())
|
||||
return;
|
||||
// calculate the motion based on model-space motion and global basis
|
||||
gd::Basis const &model_basis{this->model_node->get_global_basis()};
|
||||
this->anim_tree->set_walk_speed(gd::Math::max(0.f, model_basis.get_column(2).dot(this->camera_parent->get_basis().get_column(2))));
|
||||
gd::Vector3 const local_motion{this->anim_tree->get_root_motion_position()};
|
||||
gd::Vector3 const motion {
|
||||
local_motion.x * model_basis.get_column(0) +
|
||||
local_motion.y * model_basis.get_column(1) +
|
||||
local_motion.z * model_basis.get_column(2) +
|
||||
(this->is_on_floor() ? gd::Vector3{} : gd::Vector3{0.f, -1.f, 0.f})
|
||||
(this->is_on_floor() ? gd::Vector3{} : gd::Vector3{0.f, -1.f, 0.f}) // add some gravity if required
|
||||
};
|
||||
// set velocity and move
|
||||
this->set_velocity(motion / delta);
|
||||
}
|
||||
|
||||
void Player::_physics_process(double delta [[maybe_unused]]) {
|
||||
if(gd::Engine::get_singleton()->is_editor_hint())
|
||||
return;
|
||||
this->move_and_slide();
|
||||
}
|
||||
|
||||
void Player::process_transform_camera(double delta) {
|
||||
this->camera_parent->set_global_position(this->get_global_position());
|
||||
float const camera_speed{float(delta) * (this->fsm->get_current_node().contains("[aim]") ? this->AIMING_CAMERA_ROTATION_SPEED : this->CAMERA_ROTATION_SPEED)};
|
||||
float const camera_speed{float(delta) * (this->anim_tree->match_tags(PlayerAnimTree::Aim) ? this->AIMING_CAMERA_ROTATION_SPEED : this->CAMERA_ROTATION_SPEED)};
|
||||
this->camera_parent->rotate_y(this->input_directions.x * -camera_speed);
|
||||
}
|
||||
|
||||
void Player::process_rotate(double delta) {
|
||||
if(this->fsm->get_current_node().contains("[turn")) {
|
||||
if(this->anim_tree->match_tags(PlayerAnimTree::Tags::Turn)) {
|
||||
//! the signed angle difference between the left axes of the camera parent and Player
|
||||
float const diff = -this->camera_parent->get_global_basis().get_column(0).signed_angle_to(this->get_global_basis().get_column(0), {0.f, 1.f, 0.f});
|
||||
float const diff{-this->camera_parent->get_global_basis().get_column(0).signed_angle_to(this->get_global_basis().get_column(0), {0.f, 1.f, 0.f})};
|
||||
float const dir{gd::Math::sign(diff)};
|
||||
//! the maximum rotation to allow for this frame
|
||||
float const speed{float(delta) * this->ROTATION_SPEED};
|
||||
float const actual_speed{speed < gd::Math::abs(diff) ? gd::Math::sign(diff) * speed : diff};
|
||||
float const actual_speed{speed < gd::Math::abs(diff) ? dir * speed : diff};
|
||||
// rotate by max allowed or full difference, whichever has the smaller magnitude
|
||||
this->rotate_y(actual_speed);
|
||||
this->anim_tree->set("parameters/Actions/Stationary [turn]/Turn/blend_position", diff * M_PI_2f);
|
||||
} else {
|
||||
this->anim_tree->set("parameters/Actions/Stationary [turn_animated]/blend_position", 0.f);
|
||||
this->anim_tree->set_target_turn_speed(gd::Math::clamp(diff * 2.f, -1.f, 1.f) * M_PI_2f *0.9f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,20 +75,20 @@ void Player::_on_dir_horizontal(gd::Ref<gd::InputEvent>, float value) {
|
|||
|
||||
void Player::_on_dir_vertical(gd::Ref<gd::InputEvent>, float value) {
|
||||
this->input_directions.y = value;
|
||||
this->anim_tree->set_aim_weapon(value <= -0.9f);
|
||||
this->anim_tree->set_is_walking(value > 0.5f);
|
||||
}
|
||||
|
||||
void Player::_on_fire(gd::Ref<gd::InputEvent>, float value) {
|
||||
if(value > 0.f) {
|
||||
this->input_fire = 0.5;
|
||||
}
|
||||
void Player::_on_fire(gd::Ref<gd::InputEvent> event, float) {
|
||||
if(event->is_pressed())
|
||||
this->anim_tree->set_fire_weapon();
|
||||
}
|
||||
|
||||
void Player::_on_run(gd::Ref<gd::InputEvent> event, float) {
|
||||
if(event->is_pressed())
|
||||
this->anim_tree->set_is_running();
|
||||
}
|
||||
|
||||
gd::Vector2 Player::get_input_directions() const {
|
||||
return this->input_directions;
|
||||
}
|
||||
|
||||
bool Player::get_input_fire() {
|
||||
bool const val = this->input_fire > 0.0;
|
||||
this->input_fire = 0.0;
|
||||
return val;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define TR_PLAYER_HPP
|
||||
|
||||
#include "utils/player_input.hpp"
|
||||
#include <godot_cpp/classes/animation_tree.hpp>
|
||||
#include "player_anim_tree.hpp"
|
||||
#include <godot_cpp/classes/character_body3d.hpp>
|
||||
#include <godot_cpp/classes/animation_node_state_machine_playback.hpp>
|
||||
namespace gd = godot;
|
||||
|
@ -20,20 +20,19 @@ public:
|
|||
|
||||
void _on_dir_horizontal(gd::Ref<gd::InputEvent>, float value);
|
||||
void _on_dir_vertical(gd::Ref<gd::InputEvent>, float value);
|
||||
void _on_fire(gd::Ref<gd::InputEvent>, float value);
|
||||
void _on_fire(gd::Ref<gd::InputEvent> event, float);
|
||||
void _on_run(gd::Ref<gd::InputEvent> event, float);
|
||||
|
||||
gd::Vector2 get_input_directions() const;
|
||||
bool get_input_fire();
|
||||
private:
|
||||
gd::AnimationTree *anim_tree{nullptr};
|
||||
gd::AnimationNodeStateMachinePlayback *fsm{nullptr};
|
||||
PlayerAnimTree *anim_tree{nullptr};
|
||||
gd::Node3D *camera_parent{nullptr};
|
||||
utils::PlayerInput *input{nullptr};
|
||||
gd::Node3D *model_node{nullptr};
|
||||
gd::Vector2 input_directions{0.f, 0.f};
|
||||
double input_fire{0.0};
|
||||
|
||||
float const ROTATION_SPEED{1.5f};
|
||||
float const ROTATION_SPEED{1.8f};
|
||||
float const CAMERA_ROTATION_SPEED{2.f};
|
||||
float const AIMING_CAMERA_ROTATION_SPEED{1.f};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
#include "player_anim_tree.hpp"
|
||||
#include "utils/godot_macros.hpp"
|
||||
#include <godot_cpp/variant/utility_functions.hpp>
|
||||
|
||||
void PlayerAnimTree::_bind_methods() {
|
||||
#define CLASSNAME PlayerAnimTree
|
||||
GDPROPERTY(target_turn_speed, gd::Variant::FLOAT);
|
||||
GDPROPERTY(is_walking, gd::Variant::FLOAT);
|
||||
GDPROPERTY(walk_speed, gd::Variant::FLOAT);
|
||||
GDFUNCTION(get_is_running);
|
||||
GDPROPERTY(aim_weapon, gd::Variant::BOOL);
|
||||
GDFUNCTION(get_fire_weapon);
|
||||
}
|
||||
|
||||
void PlayerAnimTree::_ready() {
|
||||
this->fsm = this->get("parameters/Actions/playback");
|
||||
}
|
||||
|
||||
void PlayerAnimTree::_process(double delta) {
|
||||
if(gd::Engine::get_singleton()->is_editor_hint())
|
||||
return;
|
||||
this->turn_speed = gd::Math::move_toward(this->turn_speed, this->target_turn_speed, float(delta * 30.));
|
||||
this->commit_turn_speed();
|
||||
this->update_tags(this->fsm->get_current_node());
|
||||
this->fire_weapon -= delta;
|
||||
this->running_time -= delta;
|
||||
}
|
||||
|
||||
void PlayerAnimTree::set_target_turn_speed(float value) {
|
||||
this->target_turn_speed = value;
|
||||
}
|
||||
|
||||
float PlayerAnimTree::get_target_turn_speed() const {
|
||||
return this->target_turn_speed;
|
||||
}
|
||||
|
||||
void PlayerAnimTree::set_is_walking(bool value) {
|
||||
this->is_walking = value;
|
||||
}
|
||||
|
||||
bool PlayerAnimTree::get_is_walking() const {
|
||||
return this->is_walking;
|
||||
}
|
||||
|
||||
void PlayerAnimTree::set_walk_speed(float value) {
|
||||
this->walk_speed = value;
|
||||
this->commit_walk_speed();
|
||||
}
|
||||
|
||||
float PlayerAnimTree::get_walk_speed() const {
|
||||
return this->walk_speed;
|
||||
}
|
||||
|
||||
void PlayerAnimTree::set_is_running() {
|
||||
this->running_time = 0.25;
|
||||
}
|
||||
|
||||
bool PlayerAnimTree::get_is_running() const {
|
||||
return this->running_time > 0.0;
|
||||
}
|
||||
|
||||
void PlayerAnimTree::set_aim_weapon(bool value) {
|
||||
this->aim_weapon = value;
|
||||
}
|
||||
|
||||
bool PlayerAnimTree::get_aim_weapon() const {
|
||||
return this->aim_weapon;
|
||||
}
|
||||
|
||||
void PlayerAnimTree::set_fire_weapon() {
|
||||
this->fire_weapon = 0.5f;
|
||||
}
|
||||
|
||||
bool PlayerAnimTree::get_fire_weapon() {
|
||||
bool const is_set = this->fire_weapon > 0.f;
|
||||
this->fire_weapon = 0.f;
|
||||
return is_set;
|
||||
}
|
||||
|
||||
bool PlayerAnimTree::match_tags(Tags tags) const {
|
||||
return (this->current_tags & tags) != Tags::None;
|
||||
}
|
||||
|
||||
void PlayerAnimTree::update_tags(gd::StringName const &anim) {
|
||||
if(anim != this->last_known_anim && this->fsm->get_travel_path().size() <= 1) {
|
||||
this->last_known_anim = anim;
|
||||
this->current_tags = Tags::None;
|
||||
if(anim.contains("[turn]"))
|
||||
this->current_tags = Tags(this->current_tags | Tags::Turn);
|
||||
if(anim.contains("[aim]"))
|
||||
this->current_tags = Tags(this->current_tags | Tags::Aim);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerAnimTree::commit_turn_speed() {
|
||||
this->set("parameters/Actions/Stationary [turn]/Turn/blend_position", this->turn_speed);
|
||||
}
|
||||
|
||||
void PlayerAnimTree::commit_walk_speed() {
|
||||
this->set("parameters/Actions/Walk [turn]/Speed/blend_amount", this->walk_speed);
|
||||
this->set("parameters/Actions/Run/Speed/blend_amount", this->walk_speed);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef PLAYER_ANIM_TREE_HPP
|
||||
#define PLAYER_ANIM_TREE_HPP
|
||||
|
||||
#include "utils/godot_macros.hpp"
|
||||
#include <godot_cpp/classes/animation_tree.hpp>
|
||||
#include <godot_cpp/classes/animation_node_state_machine_playback.hpp>
|
||||
namespace gd = godot;
|
||||
|
||||
class PlayerAnimTree : public gd::AnimationTree {
|
||||
GDCLASS(PlayerAnimTree, gd::AnimationTree);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
enum Tags : unsigned {
|
||||
None = 0x0,
|
||||
Turn = 0x1,
|
||||
Aim = 0x2
|
||||
};
|
||||
public:
|
||||
virtual void _ready() override;
|
||||
virtual void _process(double delta) override;
|
||||
|
||||
void set_target_turn_speed(float value);
|
||||
float get_target_turn_speed() const;
|
||||
void set_is_walking(bool value);
|
||||
bool get_is_walking() const;
|
||||
void set_walk_speed(float value);
|
||||
float get_walk_speed() const;
|
||||
void set_is_running();
|
||||
bool get_is_running() const;
|
||||
void set_aim_weapon(bool value);
|
||||
bool get_aim_weapon() const;
|
||||
void set_fire_weapon();
|
||||
bool get_fire_weapon();
|
||||
bool match_tags(Tags tags) const;
|
||||
private:
|
||||
void update_tags(gd::StringName const &anim);
|
||||
void commit_turn_speed();
|
||||
void commit_walk_speed();
|
||||
private:
|
||||
gd::Ref<gd::AnimationNodeStateMachinePlayback> fsm;
|
||||
float turn_speed{0.f};
|
||||
float target_turn_speed{0.f};
|
||||
bool is_walking{false};
|
||||
float walk_speed{0.f};
|
||||
double running_time{0.0};
|
||||
bool aim_weapon{false};
|
||||
double fire_weapon{0.0};
|
||||
Tags current_tags{Tags::None};
|
||||
gd::StringName last_known_anim{};
|
||||
};
|
||||
|
||||
#endif // !PLAYER_ANIM_HPP
|
|
@ -16,6 +16,7 @@ void initialize_gdextension_types(ModuleInitializationLevel p_level)
|
|||
}
|
||||
utils::godot_cpp_utils_register_types();
|
||||
GDREGISTER_CLASS(Player);
|
||||
GDREGISTER_CLASS(PlayerAnimTree);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
|
|
Loading…
Reference in New Issue