feat: base character class and player character

This commit is contained in:
Sara Gerretsen 2025-12-24 15:24:21 +01:00
parent 61c9925b40
commit 79bf5c6ac0
5 changed files with 144 additions and 0 deletions

View file

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

View file

@ -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<CharacterData> data{};
Vector2 world_movement_direction{};
public:
GET_SET_FNS(Ref<CharacterData>, data);
};

View file

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

View file

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

View file

@ -1,11 +1,16 @@
#include "register_types.h" #include "register_types.h"
#include "authority/character.h"
#include "authority/player_character.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) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return; return;
} }
ClassDB::register_class<CharacterData>();
ClassDB::register_class<Character>();
ClassDB::register_class<PlayerCharacter>();
} }
void uninitialize_authority_module(ModuleInitializationLevel p_level) { void uninitialize_authority_module(ModuleInitializationLevel p_level) {