103 lines
4.1 KiB
GDScript
103 lines
4.1 KiB
GDScript
class_name PlayerCamera3D
|
|
extends Node3D
|
|
|
|
@export var follow_target : Node3D
|
|
@export_range(0.0, 5.0, 0.05) var follow_max_distance : float = 1.0
|
|
@export_range(0.05, 20.0, 0.05) var follow_speed : float = 1.0
|
|
@export var follow_distance_curve : Curve
|
|
@export var animation_tree : AnimationTree
|
|
|
|
@export_category("Nodes")
|
|
@export var camera : Camera3D
|
|
@export var state_chart : StateChart
|
|
@export var gimbal_x : Node3D
|
|
@export var gimbal_y : Node3D
|
|
|
|
@export_category("Input Settings")
|
|
@export var _camera_movement_speed : Vector2 = Vector2.ONE
|
|
@export var _camera_accelerate_speed : float = 1.0
|
|
|
|
@export_category("Input Resources")
|
|
@export var _camera_movement_resource : InputResource
|
|
|
|
var _reset_orientation : Vector2 = Vector2.ZERO
|
|
|
|
var _target_camera_orientation : Vector2 = Vector2.ZERO
|
|
|
|
var _debug_input_resource : InputResource
|
|
|
|
|
|
func _ready() -> void:
|
|
_reset_orientation = Vector2(gimbal_y.rotation.y, gimbal_x.rotation.x)
|
|
if follow_target: global_position = follow_target.global_position
|
|
|
|
_target_camera_orientation = _reset_orientation
|
|
|
|
InputHandler.add_input_resource(self, _camera_movement_resource)
|
|
|
|
_debug_input_resource = load("uid://xh7ux5jkfxle")
|
|
InputHandler.add_input_resource(self, _debug_input_resource)
|
|
|
|
top_level = true
|
|
|
|
|
|
func _physics_process(_delta:float) -> void:
|
|
gimbal_y.rotation.y = lerp_angle(gimbal_y.rotation.y, -_target_camera_orientation.x, _camera_accelerate_speed * _delta)
|
|
gimbal_x.rotation.x = lerp_angle(gimbal_x.rotation.x, _target_camera_orientation.y, _camera_accelerate_speed * _delta)
|
|
|
|
if follow_target:
|
|
var max_position : Vector3 = (global_position - follow_target.global_position).normalized() * follow_max_distance
|
|
global_position = lerp(global_position, follow_target.global_position, follow_distance_curve.sample_baked(max_position.length()) * follow_speed * _delta)
|
|
if global_position.distance_squared_to(follow_target.global_position) > (follow_target.global_position + max_position).distance_squared_to(follow_target.global_position):
|
|
global_position = (follow_target.global_position + max_position)
|
|
|
|
|
|
func _on_camera_rotate_2d(_delta:float, _vector:Vector2) -> void:
|
|
_on_camera_rotate(_delta, _vector)
|
|
func _on_camera_rotate_mouse(_delta:float, _vector:Vector2) -> void:
|
|
_on_camera_rotate(_delta, _vector)
|
|
func _on_camera_rotate(_delta:float, _vector:Vector2) -> void:
|
|
_target_camera_orientation += _vector * _camera_movement_speed * _delta
|
|
const rotation_limit = (PI / 2.0) - 0.075
|
|
_target_camera_orientation.y = clamp(_target_camera_orientation.y, -rotation_limit, rotation_limit)
|
|
|
|
func _on_camera_reset_pressed() -> void:
|
|
_target_camera_orientation = _reset_orientation
|
|
_target_camera_orientation.x -= follow_target.global_rotation.y
|
|
|
|
|
|
func _on___debug_show_performance_pressed() -> void:
|
|
DebugMenu.visible = !DebugMenu.visible
|
|
|
|
func _on___debug_debugdraw_disabled_pressed() -> void:
|
|
get_viewport().debug_draw = Viewport.DEBUG_DRAW_DISABLED
|
|
func _on___debug_debugdraw_wireframe_pressed() -> void:
|
|
get_viewport().debug_draw = Viewport.DEBUG_DRAW_WIREFRAME
|
|
func _on___debug_debugdraw_normalbuffer_pressed() -> void:
|
|
get_viewport().debug_draw = Viewport.DEBUG_DRAW_NORMAL_BUFFER
|
|
func _on___debug_debugdraw_overdraw_pressed() -> void:
|
|
get_viewport().debug_draw = Viewport.DEBUG_DRAW_OVERDRAW
|
|
func _on___debug_debugdraw_ssao_pressed() -> void:
|
|
get_viewport().debug_draw = Viewport.DEBUG_DRAW_SSAO
|
|
func _on___debug_debugdraw_sdfgi_pressed() -> void:
|
|
get_viewport().debug_draw = Viewport.DEBUG_DRAW_SDFGI
|
|
func _on___debug_debugdraw_ssil_pressed() -> void:
|
|
get_viewport().debug_draw = Viewport.DEBUG_DRAW_SSIL
|
|
|
|
|
|
func _on_standard_state_entered() -> void:
|
|
InputHandler.add_input_resource(self, _camera_movement_resource)
|
|
_on_camera_reset_pressed()
|
|
|
|
|
|
func _on_slice_time_state_entered() -> void:
|
|
InputHandler.remove_input_resource(self, _camera_movement_resource)
|
|
_on_camera_reset_pressed()
|
|
animation_tree["parameters/playback"].travel("slice_time_zoom_in")
|
|
|
|
func _on_slice_time_state_exited() -> void:
|
|
animation_tree["parameters/playback"].travel("standard_zoom")
|
|
|
|
func _on_slice_time_state_physics_processing(_delta:float) -> void:
|
|
gimbal_y.global_rotation.y = follow_target.global_rotation.y
|