break-utopia/modules/break_utopia/player_body.cpp

121 lines
3 KiB
C++

#include "player_body.h"
#include "core/config/engine.h"
#include "core/input/input.h"
#include "macros.h"
#include "scene/3d/camera_3d.h"
#include "scene/main/node.h"
#include "scene/main/viewport.h"
void PlayerBody::_bind_methods() {
}
void PlayerBody::physics_process(double delta) {
move_and_slide();
}
void PlayerBody::on_child_entered(Node *node) {
if (CharacterState * state{ cast_to<CharacterState>(node) }) {
if (!this->default_state) {
this->default_state = state;
}
}
}
void PlayerBody::_notification(int what) {
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
switch (what) {
default:
return;
case NOTIFICATION_ENTER_TREE:
set_process_unhandled_input(true);
set_physics_process(true);
if (!is_ready()) {
connect("child_entered_tree", callable_mp(this, &self_type::on_child_entered));
}
return;
case NOTIFICATION_READY:
if (this->default_state) {
this->default_state->set_state_active(true);
}
return;
case NOTIFICATION_PHYSICS_PROCESS:
physics_process(get_physics_process_delta_time());
return;
}
}
void PlayerBody::process_movement_input() {
this->movement_input = {
Input::get_singleton()->get_axis("move_left", "move_right"),
Input::get_singleton()->get_axis("move_forward", "move_backward")
};
this->movement_input.normalize();
}
void PlayerBody::unhandled_input(Ref<InputEvent> const &what) {
if (what->is_action("move_forward") || what->is_action("move_backward") || what->is_action("move_left") || what->is_action("move_right")) {
process_movement_input();
}
}
Vector3 PlayerBody::get_transformed_movement_input() const {
Basis const basis{ get_viewport()->get_camera_3d()->get_global_basis() };
Vector3 forward{ basis.get_column(2) };
Vector3 left{ basis.get_column(0) };
return forward * this->movement_input.y + left * this->movement_input.x;
}
String const CharacterState::sig_state_entered{ "state_entered" };
String const CharacterState::sig_state_exited{ "state_exited" };
void CharacterState::_bind_methods() {
ADD_SIGNAL(MethodInfo(sig_state_entered));
ADD_SIGNAL(MethodInfo(sig_state_exited));
}
void CharacterState::_notification(int what) {
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
switch (what) {
default:
return;
case NOTIFICATION_ENTER_TREE:
// turn these off just in case
set_process(false);
set_physics_process(false);
set_process_input(false);
set_process_unhandled_input(false);
return;
}
}
void CharacterState::switch_state(NodePath path) {
this->set_state_active(false);
stack_state(path);
}
void CharacterState::stack_state(NodePath path) {
if (CharacterState * new_state{ cast_to<CharacterState>(get_node(path)) }) {
new_state->set_state_active(true);
}
}
void CharacterState::state_entered() {}
void CharacterState::state_exited() {}
void CharacterState::set_state_active(bool active) {
if (active != this->active_state) {
if (active) {
state_entered();
emit_signal(sig_state_entered);
} else {
state_exited();
emit_signal(sig_state_exited);
}
}
this->active_state = active;
}