#include #include #include #include #include #include #include #include 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("Armature"); DEV_ASSERT(m_Mesh); m_AnimationTree = get_node("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"); for (int i = 0; i < skeleton->get_child_count(); i++) { auto* bodyPart = Object::cast_to(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("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