58 lines
2.0 KiB
GDScript3
58 lines
2.0 KiB
GDScript3
|
class_name PlayerCharacterController extends Node
|
||
|
|
||
|
@export var camera: Camera3D = null
|
||
|
@export var character: Character = null
|
||
|
@export var camera_sensitivity: float = 2.0
|
||
|
@export var camera_lerp_speed: float = 4.0
|
||
|
@export var camera_distance: float = 5.0
|
||
|
@export var camera_min_distance: float = 2.0
|
||
|
@export var camera_max_distance: float = 10.0
|
||
|
@export var camera_pitch: float = -0.5
|
||
|
@export var camera_min_pitch: float = -1.0
|
||
|
@export var camera_max_pitch: float = -0.2
|
||
|
|
||
|
@onready var camera_yaw: float = (
|
||
|
character.global_rotation.y if character else 0.0
|
||
|
)
|
||
|
|
||
|
func _physics_process(delta: float) -> void:
|
||
|
if camera && character:
|
||
|
var look_input := Vector3(
|
||
|
Input.get_axis(&'look_left', &'look_right'),
|
||
|
Input.get_axis(&'look_down', &'look_up'),
|
||
|
Input.get_axis(&'zoom_in', &'zoom_out')
|
||
|
)
|
||
|
camera_distance = clamp(
|
||
|
camera_distance + PI*look_input.z*camera_sensitivity*delta,
|
||
|
camera_min_distance, camera_max_distance
|
||
|
)
|
||
|
camera_yaw = fposmod(
|
||
|
camera_yaw - look_input.x*camera_sensitivity*delta,
|
||
|
2.0*PI
|
||
|
)
|
||
|
camera_pitch = clamp(
|
||
|
camera_pitch + look_input.y*camera_sensitivity*delta,
|
||
|
camera_min_pitch, camera_max_pitch
|
||
|
)
|
||
|
var bas := Basis.IDENTITY.rotated(
|
||
|
Vector3.RIGHT, camera_pitch
|
||
|
).rotated(
|
||
|
Vector3.UP, camera_yaw
|
||
|
)
|
||
|
bas = Basis.looking_at(-bas.z, character.ground_normal)
|
||
|
var posn := character.global_position + camera_distance*bas.z
|
||
|
var lerp_weight: float = 1.0 - 0.5**(camera_lerp_speed*delta)
|
||
|
camera.global_basis = camera.global_basis.slerp(bas, lerp_weight)
|
||
|
camera.global_position = lerp(camera.global_position, posn, lerp_weight)
|
||
|
var move_input := Vector2(
|
||
|
Input.get_axis(&'move_left', &'move_right'),
|
||
|
Input.get_axis(&'move_forward', &'move_backward')
|
||
|
)
|
||
|
character.global_impetus = (
|
||
|
move_input.x*camera.basis.x +
|
||
|
move_input.y*camera.basis.z
|
||
|
)
|
||
|
character.jump_impetus = Input.is_action_pressed(&'jump')
|
||
|
character.action1_impetus = Input.is_action_pressed(&'action1')
|
||
|
character.action2_impetus = Input.is_action_pressed(&'action2')
|