translated movement to state machine
This commit is contained in:
parent
c3ff41e1e6
commit
ea3b68aef8
9 changed files with 98 additions and 19 deletions
|
|
@ -1,2 +1,5 @@
|
||||||
((c++-mode . ((mode . clang-format-on-save)))
|
((c++-mode . ((mode . clang-format-on-save)))
|
||||||
(c-mode . ((mode . c++))))
|
(c-mode . ((mode . c++)))
|
||||||
|
(nil . ((projectile-project-compilation-cmd . "just build")
|
||||||
|
(projectile-project-run-cmd . "engine/bin/godot.linuxbsd.editor.dev.x86_64.llvm --path project -e")
|
||||||
|
(projectile-project-test-cmd . "engine/bin/godot.linuxbsd.editor.dev.x86.llvm --path project"))))
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ void CharacterState::_notification(int what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterState::switch_to_state(String value) {
|
void CharacterState::switch_to_state(String value) {
|
||||||
if (this->state_active) {
|
if (!this->state_active) {
|
||||||
print_error(vformat("Attempt to switch from inactive state %s to new state %s", get_path(), value));
|
print_error(vformat("Attempt to switch from inactive state %s to new state %s", get_path(), value));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +75,7 @@ void CharacterState::switch_to_state(String value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterState::stack_state_dependent(String value) {
|
void CharacterState::stack_state_dependent(String value) {
|
||||||
if (this->state_active) {
|
if (!this->state_active) {
|
||||||
print_error(vformat("Attempt to stack dependent state %s from inactive state %s", value, get_path()));
|
print_error(vformat("Attempt to stack dependent state %s from inactive state %s", value, get_path()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -87,8 +87,16 @@ void CharacterState::stack_state_dependent(String value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CharacterState::notify_dependent_inactive(CharacterState *state) {
|
||||||
|
if (!this->state_active) {
|
||||||
|
print_error(vformat("Received notification that dependent state %s became inactive, while depending state %s was inactive", state->get_path(), get_path()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->dependent_states.erase(state);
|
||||||
|
}
|
||||||
|
|
||||||
void CharacterState::stack_state_independent(String value) {
|
void CharacterState::stack_state_independent(String value) {
|
||||||
if (this->state_active) {
|
if (!this->state_active) {
|
||||||
print_error(vformat("Attempt to stack state %s from inactive state %s", value, get_path()));
|
print_error(vformat("Attempt to stack state %s from inactive state %s", value, get_path()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -101,12 +109,15 @@ void CharacterState::stack_state_independent(String value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterState::set_state_active(bool active) {
|
void CharacterState::set_state_active(bool active) {
|
||||||
if (this->state_active == active) {
|
if (this->state_active != active) {
|
||||||
this->state_active = active;
|
this->state_active = active;
|
||||||
if (active) {
|
if (active) {
|
||||||
state_entered();
|
state_entered();
|
||||||
} else {
|
} else {
|
||||||
state_exited();
|
state_exited();
|
||||||
|
if (this->depending_state && this->depending_state->state_active) {
|
||||||
|
this->depending_state->notify_dependent_inactive(this);
|
||||||
|
}
|
||||||
this->depending_state = nullptr;
|
this->depending_state = nullptr;
|
||||||
for (CharacterState *state : this->dependent_states) {
|
for (CharacterState *state : this->dependent_states) {
|
||||||
state->set_state_active(false);
|
state->set_state_active(false);
|
||||||
|
|
@ -115,3 +126,11 @@ void CharacterState::set_state_active(bool active) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CharacterState::get_state_active() const {
|
||||||
|
return this->state_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
Character *CharacterState::get_character() const {
|
||||||
|
return this->character;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ protected:
|
||||||
void _notification(int what);
|
void _notification(int what);
|
||||||
void switch_to_state(String state);
|
void switch_to_state(String state);
|
||||||
void stack_state_dependent(String state);
|
void stack_state_dependent(String state);
|
||||||
|
void notify_dependent_inactive(CharacterState *dependent);
|
||||||
void stack_state_independent(String state);
|
void stack_state_independent(String state);
|
||||||
virtual void state_entered() {}
|
virtual void state_entered() {}
|
||||||
virtual void state_exited() {}
|
virtual void state_exited() {}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,75 @@
|
||||||
#include "player_states.h"
|
#include "player_states.h"
|
||||||
|
#include "core/input/input.h"
|
||||||
|
#include "core/math/basis.h"
|
||||||
|
#include "scene/3d/camera_3d.h"
|
||||||
|
#include "scene/main/viewport.h"
|
||||||
|
|
||||||
void PlayerInputState::_bind_methods() {}
|
void PlayerInputState::_bind_methods() {}
|
||||||
|
|
||||||
void PlayerInputState::process(double delta) {}
|
void PlayerInputState::unhandled_input(Ref<InputEvent> const &what) {
|
||||||
|
bool const is_move_vertical{ what->is_action("move_forward") || what->is_action("move_backward") };
|
||||||
|
bool const is_move_horizontal{ what->is_action("move_right") || what->is_action("move_left") };
|
||||||
|
if (is_move_vertical || is_move_horizontal) {
|
||||||
|
stack_state_dependent("PlayerMovementState");
|
||||||
|
get_viewport()->set_input_as_handled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerInputState::_notification(int what) {
|
void PlayerInputState::state_entered() {
|
||||||
|
set_process_unhandled_input(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerInputState::state_exited() {
|
||||||
|
set_process_unhandled_input(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerMovementState::_bind_methods() {}
|
||||||
|
|
||||||
|
void PlayerMovementState::process(double delta) {
|
||||||
|
Basis const basis{ get_viewport()->get_camera_3d()->get_global_basis() };
|
||||||
|
Vector2 backward{ basis.get_column(0).x, basis.get_column(0).z };
|
||||||
|
if (backward.is_zero_approx()) {
|
||||||
|
backward = Vector2{ basis.get_column(1).x, basis.get_column(1).z };
|
||||||
|
}
|
||||||
|
Vector2 const right{ basis.get_column(2).x, basis.get_column(2).z };
|
||||||
|
get_character()->set_movement((backward.normalized() * this->movement.x + right.normalized() * this->movement.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerMovementState::_notification(int what) {
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (what) {
|
switch (what) {
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
case NOTIFICATION_READY:
|
||||||
|
set_process_input(true);
|
||||||
|
return;
|
||||||
case NOTIFICATION_PROCESS:
|
case NOTIFICATION_PROCESS:
|
||||||
process(get_process_delta_time());
|
process(get_process_delta_time());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerInputState::state_entered() {
|
void PlayerMovementState::input(Ref<InputEvent> const &what) {
|
||||||
|
bool const is_move_vertical{ what->is_action("move_forward") || what->is_action("move_backward") };
|
||||||
|
bool const is_move_horizontal{ what->is_action("move_right") || what->is_action("move_left") };
|
||||||
|
if (is_move_vertical || is_move_horizontal) {
|
||||||
|
this->movement = {
|
||||||
|
Input::get_singleton()->get_axis("move_left", "move_right"),
|
||||||
|
Input::get_singleton()->get_axis("move_forward", "move_backward")
|
||||||
|
};
|
||||||
|
this->movement.normalize();
|
||||||
|
}
|
||||||
|
if (this->get_state_active() && this->movement.is_zero_approx()) {
|
||||||
|
set_state_active(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerMovementState::state_entered() {
|
||||||
set_process(true);
|
set_process(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerInputState::state_exited() {
|
void PlayerMovementState::state_exited() {
|
||||||
set_process(false);
|
set_process(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,11 @@
|
||||||
class PlayerInputState : public CharacterState {
|
class PlayerInputState : public CharacterState {
|
||||||
GDCLASS(PlayerInputState, CharacterState);
|
GDCLASS(PlayerInputState, CharacterState);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
void process(double delta);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int what);
|
|
||||||
void unhandled_input(Ref<InputEvent> const &event) override;
|
void unhandled_input(Ref<InputEvent> const &event) override;
|
||||||
void state_entered() override;
|
void state_entered() override;
|
||||||
void state_exited() override;
|
void state_exited() override;
|
||||||
|
|
||||||
public:
|
|
||||||
Vector2 input{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayerMovementState : public CharacterState {
|
class PlayerMovementState : public CharacterState {
|
||||||
|
|
@ -24,6 +19,8 @@ class PlayerMovementState : public CharacterState {
|
||||||
void process(double delta);
|
void process(double delta);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void _notification(int what);
|
||||||
|
void input(Ref<InputEvent> const &event) override;
|
||||||
void state_entered() override;
|
void state_entered() override;
|
||||||
void state_exited() override;
|
void state_exited() override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "register_types.h"
|
#include "register_types.h"
|
||||||
|
|
||||||
#include "authority/character.h"
|
#include "authority/character.h"
|
||||||
|
#include "authority/player_states.h"
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
|
|
||||||
void initialize_authority_module(ModuleInitializationLevel p_level) {
|
void initialize_authority_module(ModuleInitializationLevel p_level) {
|
||||||
|
|
@ -10,6 +11,8 @@ void initialize_authority_module(ModuleInitializationLevel p_level) {
|
||||||
ClassDB::register_class<CharacterData>();
|
ClassDB::register_class<CharacterData>();
|
||||||
ClassDB::register_class<Character>();
|
ClassDB::register_class<Character>();
|
||||||
ClassDB::register_class<CharacterState>();
|
ClassDB::register_class<CharacterState>();
|
||||||
|
ClassDB::register_class<PlayerInputState>();
|
||||||
|
ClassDB::register_class<PlayerMovementState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitialize_authority_module(ModuleInitializationLevel p_level) {
|
void uninitialize_authority_module(ModuleInitializationLevel p_level) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_resource type="CharacterData" format=3 uid="uid://bmudhddb0vedg"]
|
[gd_resource type="CharacterData" format=3 uid="uid://bmudhddb0vedg"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
speed = 1.0
|
speed = 2.0
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
[gd_scene format=3 uid="uid://dcqd0wo5y5a1g"]
|
[gd_scene format=3 uid="uid://dcqd0wo5y5a1g"]
|
||||||
|
|
||||||
|
[ext_resource type="CharacterData" uid="uid://bmudhddb0vedg" path="res://data/default_player_character.tres" id="1_jy05a"]
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_vcg8s"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_vcg8s"]
|
||||||
|
|
||||||
[sub_resource type="CylinderMesh" id="CylinderMesh_5kd2n"]
|
[sub_resource type="CylinderMesh" id="CylinderMesh_5kd2n"]
|
||||||
|
|
||||||
[node name="PlayerCharacter" type="PlayerCharacter" unique_id=1435471129]
|
[node name="PlayerCharacter" type="Character" unique_id=1694717421]
|
||||||
|
data = ExtResource("1_jy05a")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=511026275]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=511026275]
|
||||||
shape = SubResource("CapsuleShape3D_vcg8s")
|
shape = SubResource("CapsuleShape3D_vcg8s")
|
||||||
|
|
@ -13,4 +16,10 @@ shape = SubResource("CapsuleShape3D_vcg8s")
|
||||||
mesh = SubResource("CylinderMesh_5kd2n")
|
mesh = SubResource("CylinderMesh_5kd2n")
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="." unique_id=932811285]
|
[node name="Camera3D" type="Camera3D" parent="." unique_id=932811285]
|
||||||
transform = Transform3D(1, 0, 0, 0, 0.90373915, 0.42808357, 0, -0.42808357, 0.90373915, 0, 2.1840205, 3.7269862)
|
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, 1, 0, -1, -4.371139e-08, 9.536743e-07, 18.920525, -0.37265897)
|
||||||
|
current = true
|
||||||
|
|
||||||
|
[node name="PlayerInputState" type="PlayerInputState" parent="." unique_id=1290843255]
|
||||||
|
start_active = true
|
||||||
|
|
||||||
|
[node name="PlayerMovementState" type="PlayerMovementState" parent="." unique_id=71639209]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://cv0ub3llm3jew"]
|
[gd_scene format=3 uid="uid://cv0ub3llm3jew"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://dcqd0wo5y5a1g" path="res://objects/player_character.tscn" id="1_kyfjp"]
|
[ext_resource type="PackedScene" uid="uid://dcqd0wo5y5a1g" path="res://objects/player_character.tscn" id="1_kyfjp"]
|
||||||
[ext_resource type="CharacterData" uid="uid://bmudhddb0vedg" path="res://data/default_player_character.tres" id="2_amxg5"]
|
|
||||||
|
|
||||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_kyfjp"]
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_kyfjp"]
|
||||||
sky_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1)
|
sky_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1)
|
||||||
|
|
@ -27,7 +26,6 @@ shadow_enabled = true
|
||||||
|
|
||||||
[node name="PlayerCharacter" parent="." unique_id=1435471129 instance=ExtResource("1_kyfjp")]
|
[node name="PlayerCharacter" parent="." unique_id=1435471129 instance=ExtResource("1_kyfjp")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||||
data = ExtResource("2_amxg5")
|
|
||||||
|
|
||||||
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="." unique_id=885387983]
|
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="." unique_id=885387983]
|
||||||
use_collision = true
|
use_collision = true
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue