extends CharacterBody3D
const SPEED = 15.0
const JUMP_VELOCITY = 10
const SENSITIVITY = 0.004
const GRAVITY = 9.8
var gravity_direction = Vector3.DOWN
@export var planet: StaticBody3D
@onready var mesh = $PlayerMesh
@onready var head = $PlayerHead
@onready var camera = $PlayerHead/Camera3D
# Hides the cursor
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(_delta):
# Calculate the gravity direction from the player
gravity_direction = (planet.global_position - global_position).normalized()
# Update the relative up direction
up_direction = -gravity_direction
set_up_direction(up_direction)
# Handles mouse movement
func _unhandled_input(event):
if event is InputEventMouseMotion:
head.rotate_y(-event.relative.x * SENSITIVITY)
camera.rotate_x(-event.relative.y * SENSITIVITY)
camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40), deg_to_rad(60))
func _physics_process(delta):
# If we are in the air, apply gravity over time
if not is_on_floor():
velocity += gravity_direction * GRAVITY * delta
# Apply a jump force in the opposite direction of gravity
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity += -gravity_direction * JUMP_VELOCITY
var direction = _get_oriented_input()
if is_on_floor():
velocity = direction * SPEED
rotate_player(delta)
move_and_slide()
func rotate_player(delta) -> void:
var target_transform = Transform3D()
target_transform.origin = global_position
# Find the left hand side of the player
var left_axis = -gravity_direction.cross(transform.basis.z).normalized()
# Keep the z axis the same
var my_z = global_transform.basis.z
# Set target rotation
target_transform.basis = Basis(left_axis, -gravity_direction, my_z).orthonormalized()
var current_rotation = global_transform.basis.get_rotation_quaternion()
var target_rotation = target_transform.basis.get_rotation_quaternion()
# Lerp between the two quaternions
var interpolated_rotation = current_rotation.slerp(target_rotation, delta * 15.0)
global_transform.basis = Basis(interpolated_rotation)
func _get_oriented_input() -> Vector3:
var input_dir = Input.get_vector("left", "right", "backward", "forward")
# Get the camera's global transform basis
var camera_basis = camera.global_transform.basis
# Orient the input direction using the camera's basis
var direction = camera_basis.x * input_dir.x + camera_basis.z * (-input_dir.y)
return direction.normalized() # Important to normalize the direction
This is my new full script. I believe that rotate_player works correctly now, but I am strugglign to ensure that the movement is oriented corectly with get orietned input