generated from Persson-dev/Godot-Xmake
122 lines
3.6 KiB
C++
122 lines
3.6 KiB
C++
#include <client/Player.h>
|
|
|
|
#include <godot_cpp/classes/engine.hpp>
|
|
#include <godot_cpp/classes/input.hpp>
|
|
#include <godot_cpp/classes/input_map.hpp>
|
|
#include <godot_cpp/classes/mesh_instance3d.hpp>
|
|
#include <godot_cpp/classes/skeleton3d.hpp>
|
|
#include <godot_cpp/core/class_db.hpp>
|
|
#include <godot_cpp/variant/utility_functions.hpp>
|
|
|
|
static const float WalkSpeed = 2.0;
|
|
static const float RunSpeed = 7.0;
|
|
static const float JumpStrength = 15.0;
|
|
static const float Gravity = 50.0;
|
|
|
|
static const float LerpValue = 0.15;
|
|
static const float AnimationBlend = 7.0;
|
|
|
|
namespace blitz {
|
|
|
|
using namespace godot;
|
|
|
|
void Player::_bind_methods() {}
|
|
|
|
Player::Player() : m_PeerId(0) {}
|
|
|
|
Player::~Player() {}
|
|
|
|
void Player::_ready() {
|
|
if (Engine::get_singleton()->is_editor_hint()) {
|
|
return;
|
|
}
|
|
|
|
// we set the player to an invalid position
|
|
set_position({-99999, -999999, -999999});
|
|
|
|
m_Mesh = get_node<Node3D>("Armature");
|
|
DEV_ASSERT(m_Mesh);
|
|
|
|
m_AnimationTree = get_node<AnimationTree>("AnimationTree");
|
|
DEV_ASSERT(m_AnimationTree);
|
|
}
|
|
|
|
void Player::_physics_process(float delta) {
|
|
if (godot::Engine::get_singleton()->is_editor_hint())
|
|
return;
|
|
|
|
move_and_slide();
|
|
UpdateAnimation(delta);
|
|
}
|
|
|
|
Vector3 Player::GetPosition() const {
|
|
return get_position();
|
|
}
|
|
|
|
void Player::SetPosition(const Vector3& a_Position) {
|
|
set_position(a_Position);
|
|
}
|
|
|
|
Vector3 Player::GetVelocity() const {
|
|
return get_velocity();
|
|
}
|
|
|
|
void Player::SetVelocity(const Vector3& a_Velocity) {
|
|
set_velocity(a_Velocity);
|
|
}
|
|
|
|
void Player::UpdateAnimation(float a_Delta) {
|
|
Vector3 velocity = get_velocity();
|
|
float angle = get_rotation().y;
|
|
|
|
Vector3 direction = velocity.rotated({0, 1, 0}, -angle);
|
|
if (direction.length() < 1.0f) {
|
|
direction.zero();
|
|
} else {
|
|
direction.normalize();
|
|
}
|
|
|
|
Vector2 inputDirection = Input::get_singleton()->get_vector("move_left", "move_right", "move_forwards", "move_backwards");
|
|
|
|
BlendAnimation("parameters/Movement/Side/blend_amount", direction.x, a_Delta);
|
|
BlendAnimation("parameters/Movement/Straight/blend_amount", direction.z, a_Delta);
|
|
|
|
|
|
float ratio = 0.5f - (UtilityFunctions::absf(direction.z) - UtilityFunctions::absf(direction.x)) * 0.5f;
|
|
BlendAnimation("parameters/Movement/Walking/blend_amount", ratio, a_Delta);
|
|
|
|
m_AnimationTree->set("parameters/conditions/jump", !is_on_floor() && get_velocity().y > 0.0f);
|
|
m_AnimationTree->set("parameters/conditions/is_on_floor", is_on_floor());
|
|
}
|
|
|
|
void Player::BlendAnimation(const godot::String& a_AnimationName, float a_Goal, float a_Delta) {
|
|
m_AnimationTree->set(
|
|
a_AnimationName, UtilityFunctions::lerp(m_AnimationTree->get(a_AnimationName), a_Goal, a_Delta * AnimationBlend));
|
|
}
|
|
|
|
void Player::SetModelVisible(bool a_Visible) {
|
|
auto* skeleton = m_Mesh->get_node<Skeleton3D>("Skeleton3D");
|
|
for (int i = 0; i < skeleton->get_child_count(); i++) {
|
|
auto* bodyPart = Object::cast_to<MeshInstance3D>(skeleton->get_child(i));
|
|
if (bodyPart)
|
|
bodyPart->set_cast_shadows_setting(a_Visible
|
|
? GeometryInstance3D::ShadowCastingSetting::SHADOW_CASTING_SETTING_ON
|
|
: GeometryInstance3D::ShadowCastingSetting::SHADOW_CASTING_SETTING_SHADOWS_ONLY);
|
|
}
|
|
|
|
// TODO: dirty, make it recursive
|
|
auto* pencilCase = m_Mesh->get_node<MeshInstance3D>("Skeleton3D/Hand/Pencil Case");
|
|
pencilCase->set_cast_shadows_setting(a_Visible ? GeometryInstance3D::ShadowCastingSetting::SHADOW_CASTING_SETTING_ON
|
|
: GeometryInstance3D::ShadowCastingSetting::SHADOW_CASTING_SETTING_SHADOWS_ONLY);
|
|
}
|
|
|
|
Vector3 Player::GetCameraRotation() const {
|
|
return get_rotation();
|
|
}
|
|
|
|
void Player::SetCameraRotation(const Vector3& a_Rotation) {
|
|
set_rotation(a_Rotation);
|
|
}
|
|
|
|
} // namespace blitz
|