generated from krampus/template-godot4
90 lines
2.6 KiB
GDScript
90 lines
2.6 KiB
GDScript
class_name ShotSetup extends Node3D
|
|
|
|
const PITCH_MIN := deg_to_rad(-60.0)
|
|
const PITCH_MAX := deg_to_rad(-5.0)
|
|
const ZOOM_LENGTH := 0.1
|
|
|
|
const ZOOM_MIN := 1.0
|
|
const ZOOM_MAX := 12.0
|
|
|
|
enum Phase {
|
|
AIMING,
|
|
LATERAL,
|
|
POWER,
|
|
FINISHED,
|
|
}
|
|
|
|
var base_speed: float = ProjectSettings.get_setting("game/config/controls/camera/free_camera_speed")
|
|
|
|
var x_sensitivity: float = ProjectSettings.get_setting(
|
|
"game/config/controls/camera/x_axis_sensitivity"
|
|
)
|
|
var x_acceleration: float = ProjectSettings.get_setting(
|
|
"game/config/controls/camera/x_axis_acceleration"
|
|
)
|
|
var y_sensitivity: float = ProjectSettings.get_setting(
|
|
"game/config/controls/camera/y_axis_sensitivity"
|
|
)
|
|
var y_acceleration: float = ProjectSettings.get_setting(
|
|
"game/config/controls/camera/y_axis_acceleration"
|
|
)
|
|
|
|
var invert_pitch: bool = ProjectSettings.get_setting("game/config/controls/camera/invert_pitch")
|
|
|
|
var _phase: Phase = Phase.AIMING
|
|
|
|
@onready var direction: Node3D = %Direction
|
|
@onready var pitch: Node3D = %Pitch
|
|
@onready var camera: Camera3D = %Camera
|
|
|
|
@onready var camera_distance := camera.position.z:
|
|
set = _set_camera_distance
|
|
|
|
@onready var _target_rotation := Vector2(pitch.rotation.x, direction.rotation.y)
|
|
|
|
|
|
func _set_camera_distance(value: float) -> void:
|
|
var tween := get_tree().create_tween()
|
|
tween.tween_property(camera, "position", Vector3(0, 0, value), ZOOM_LENGTH).set_trans(
|
|
Tween.TRANS_SINE
|
|
)
|
|
camera_distance = value
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event is InputEventMouseButton:
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
|
elif event is InputEventMouseMotion:
|
|
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
|
|
camera_motion((event as InputEventMouseMotion).relative)
|
|
|
|
|
|
func camera_motion(motion: Vector2) -> void:
|
|
if _phase == Phase.AIMING:
|
|
# Can only control camera while aiming
|
|
_target_rotation.y = _target_rotation.y - deg_to_rad(motion.x * x_sensitivity)
|
|
_target_rotation.x = clampf(
|
|
_target_rotation.x - deg_to_rad(motion.y * y_sensitivity) * (-1 if invert_pitch else 1),
|
|
PITCH_MIN,
|
|
PITCH_MAX
|
|
)
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if _phase == Phase.AIMING:
|
|
# Camera zoom
|
|
if Input.is_action_just_pressed("shot_zoom_in"):
|
|
camera_distance = max(camera_distance - 1.0, ZOOM_MIN)
|
|
if Input.is_action_just_pressed("shot_zoom_out"):
|
|
camera_distance = min(camera_distance + 1.0, ZOOM_MAX)
|
|
|
|
# Advance to next phase
|
|
if Input.is_action_just_pressed("shot_accept"):
|
|
_phase = Phase.LATERAL
|
|
|
|
# Rotation
|
|
direction.rotation.y = lerp_angle(
|
|
direction.rotation.y, _target_rotation.y, delta * x_acceleration
|
|
)
|
|
pitch.rotation.x = lerp_angle(pitch.rotation.x, _target_rotation.x, delta * y_acceleration)
|