feat: added running

main
Sara 2024-12-04 16:15:40 +01:00
parent 95375eae4a
commit 32df02855b
25 changed files with 2170 additions and 71 deletions

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)

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
godot/models/character_planks.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -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

BIN
godot/models/character_planks_normal.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -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)

Binary file not shown.

View File

@ -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

View File

@ -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)

Binary file not shown.

Binary file not shown.

BIN
models/modules.blend (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

View File

@ -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;
}

View File

@ -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};
};

102
src/player_anim_tree.cpp Normal file
View File

@ -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);
}

52
src/player_anim_tree.hpp Normal file
View File

@ -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

View File

@ -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"