diff --git a/modules/authority/character.cpp b/modules/authority/character.cpp new file mode 100644 index 00000000..805da5ba --- /dev/null +++ b/modules/authority/character.cpp @@ -0,0 +1,40 @@ +#include "character.h" +#include "authority/macros.h" +#include "core/config/engine.h" + +void CharacterData::_bind_methods() { + BIND_PROPERTY(Variant::FLOAT, speed); +} + +void Character::_bind_methods() { + BIND_HPROPERTY(Variant::OBJECT, data, PROPERTY_HINT_RESOURCE_TYPE, "CharacterData"); +} + +void Character::physics_process(double delta) { + Vector3 const velocity{ get_velocity() }; + Vector3 new_velocity{ velocity }; + new_velocity.x = this->world_movement_direction.x * this->data->get_speed(); + new_velocity.z = this->world_movement_direction.y * this->data->get_speed(); + set_velocity(new_velocity); + move_and_slide(); +} + +void Character::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + default: + return; + case NOTIFICATION_READY: + set_physics_process(true); + return; + case NOTIFICATION_PHYSICS_PROCESS: + physics_process(get_physics_process_delta_time()); + return; + } +} + +void Character::set_movement(Vector2 movement) { + this->world_movement_direction = movement; +} diff --git a/modules/authority/character.h b/modules/authority/character.h new file mode 100644 index 00000000..4b58ab5a --- /dev/null +++ b/modules/authority/character.h @@ -0,0 +1,35 @@ +#pragma once + +#include "authority/macros.h" +#include "core/io/resource.h" +#include "scene/3d/physics/character_body_3d.h" + +class CharacterData : public Resource { + GDCLASS(CharacterData, Resource); + static void _bind_methods(); + +private: + float speed{}; + +public: + GET_SET_FNS(float, speed); +}; + +class Character : public CharacterBody3D { + GDCLASS(Character, CharacterBody3D); + +protected: + static void _bind_methods(); + void physics_process(double delta); + void _notification(int what); + +public: + void set_movement(Vector2 movement); + +private: + Ref data{}; + Vector2 world_movement_direction{}; + +public: + GET_SET_FNS(Ref, data); +}; diff --git a/modules/authority/player_character.cpp b/modules/authority/player_character.cpp new file mode 100644 index 00000000..c2bba15e --- /dev/null +++ b/modules/authority/player_character.cpp @@ -0,0 +1,43 @@ +#include "player_character.h" +#include "core/input/input.h" +#include "scene/main/viewport.h" + +void PlayerCharacter::_bind_methods() {} + +void PlayerCharacter::process(double delta) { + Basis const basis{ get_viewport()->get_camera_3d()->get_global_basis() }; + Vector2 backward{ basis.get_column(2).x, basis.get_column(2).z }; + Vector2 right{ basis.get_column(0).x, basis.get_column(0).z }; + set_movement({ backward.normalized() * this->last_movement_input.x + right.normalized() * this->last_movement_input }); +} + +void PlayerCharacter::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + default: + return; + case NOTIFICATION_ENTER_TREE: + set_process(true); + set_process_unhandled_input(true); + return; + case NOTIFICATION_PROCESS: + process(get_process_delta_time()); + } +} + +void PlayerCharacter::unhandled_input(Ref const &what) { + if (what->is_action(input_move_left) || what->is_action(input_move_forward) || what->is_action(input_move_right) || what->is_action(input_move_backward)) { + this->last_movement_input = { + Input::get_singleton()->get_axis(input_move_left, input_move_right), + Input::get_singleton()->get_axis(input_move_backward, input_move_forward) + }; + get_viewport()->set_input_as_handled(); + } +} + +String const PlayerCharacter::input_move_left{ "move_left" }; +String const PlayerCharacter::input_move_right{ "move_right" }; +String const PlayerCharacter::input_move_forward{ "move_forward" }; +String const PlayerCharacter::input_move_backward{ "move_backward" }; diff --git a/modules/authority/player_character.h b/modules/authority/player_character.h new file mode 100644 index 00000000..4efb7b75 --- /dev/null +++ b/modules/authority/player_character.h @@ -0,0 +1,21 @@ +#pragma once + +#include "authority/character.h" + +class PlayerCharacter : public Character { + GDCLASS(PlayerCharacter, Character); + static void _bind_methods(); + +protected: + void process(double delta); + void _notification(int what); + virtual void unhandled_input(Ref const &what) override; + +private: + Vector2 last_movement_input{ 0, 0 }; + + static String const input_move_left; + static String const input_move_right; + static String const input_move_forward; + static String const input_move_backward; +}; diff --git a/modules/authority/register_types.cpp b/modules/authority/register_types.cpp index 3b8ce540..5c43d34d 100644 --- a/modules/authority/register_types.cpp +++ b/modules/authority/register_types.cpp @@ -1,11 +1,16 @@ #include "register_types.h" +#include "authority/character.h" +#include "authority/player_character.h" #include "core/object/class_db.h" void initialize_authority_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); } void uninitialize_authority_module(ModuleInitializationLevel p_level) {