commit 8e7da96bfcd52b230feaf40fbc6d4a42b80c5723
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Sat Oct 17 18:55:14 2026 +0200
Make state machine more reusable
commit 37da7248b8c33ce95cff7ef9332c5ccf6e3cd418
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Sat Oct 17 18:44:34 2026 +0200
Change aim state into flag
commit fbb3a84a12e2cabff9b36390da7483b8de7e9379
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Sat Oct 17 18:33:08 2026 +0200
Replace fixed references with ui references
commit 913955b13e9980780ac88761845d9e1f165f0d0e
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Fri Oct 16 13:32:21 2026 +0200
Update camera action handling
commit 4ce0ac13ffea473cf62c2fefd1571e9df1fbbcaa
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Fri Oct 16 13:04:39 2026 +0200
Update mounting system
commit e410eca38760955b2866eecd6ac0281e2041e76d
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Fri Oct 16 12:57:25 2026 +0200
Update aiming system
commit 4c788df485ccbff5f91fd51d9f480e495f11da5f
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Thu Oct 15 21:50:26 2026 +0200
Centralize states names into constants
commit 6059479c87d749e986a48adb520ef33121104da5
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Thu Oct 15 21:25:32 2026 +0200
Refator Crouch state into flag
commit 08faec70e770042d36eed6f173a63f3aac1f67c6
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Wed Oct 14 10:19:35 2026 +0200
Update player input management and state machine
commit 11a0aecc58c50c5862a03b4fd0b55e8db024031f
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Wed Oct 14 10:17:06 2026 +0200
Delete charizard.tres
commit 399eac2b6c64f242a1c2e12360d811127f87681c
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Tue Oct 13 18:20:45 2026 +0200
Remove unused MountedState
commit 42a3668c52fe96a7509a74290a94fc5a8084b713
Author: TheThomaas <thethomaas@protonmail.ch>
Date: Tue Oct 13 18:18:08 2026 +0200
Group grounded states under common class
128 lines
5.2 KiB
GDScript
128 lines
5.2 KiB
GDScript
extends Node3D
|
|
|
|
class_name CameraHolder
|
|
|
|
var active : bool = true : set = set_active
|
|
|
|
@export_group("Camera variables")
|
|
@export_range(1.0, 179.0, 0.1) var fov_val : float = 50.0
|
|
@export_range(0.0, 0.02, 0.0001) var mouse_sensibility : float = 0.005
|
|
@export_range(0.0, 0.02, 0.0001) var joystick_sensibility : float = 0.05
|
|
@export_range(-90.0, 90.0, 0.1) var min_limit_x : float = -80.0 #in degrees here for clearer lisibility, is converted in radians when needed
|
|
@export_range(-90.0, 90.0, 0.1) var max_limit_x : float = 10.0 #in degrees here for clearer lisibility, is converted in radians when needed
|
|
|
|
@export_group("Zoom variables")
|
|
@export var max_spring_length : float = 30.0
|
|
@export var min_spring_length : float = 3.0
|
|
@export var zoom_speed : float = 10.0
|
|
|
|
@export_group("Aim variables")
|
|
var cam_aimed : bool = false #if true, cam goes into "aim/shooter mode", above the play char shoulder
|
|
@export var aim_cam_pos : Vector3 = Vector3(1.4, 0.9, 0.0)
|
|
var aim_cam_pos_side : bool = true #false = left, true = right
|
|
@export var aim_cam_transition_speed : float = 10.0
|
|
var cam_offset : Vector3 = Vector3.ZERO #decalage actuel de la camera (interpole)
|
|
@export_range(0.1, 1.0, 0.01) var aim_distance_multiplier : float = 0.6 #1.0 = meme distance que hors visee, 0.5 = moitie moins loin
|
|
@export var min_cam_distance : float = 0.8 #distance minimale entre le pivot et la camera
|
|
var cam_distance_mult : float = 1.0 #multiplicateur actuel (interpole)
|
|
|
|
|
|
@export_group("Lock-on variables")
|
|
@export var lock_on_speed : float = 8.0
|
|
var lock_target : Node3D = null
|
|
|
|
#input : renseigne par InputManagementComponent, le CameraHolder ne connait aucun nom d'action
|
|
var player_input : InputManagementComponent
|
|
|
|
#reference variables
|
|
@export_group("References")
|
|
@export var spring_arm : SpringArm3D
|
|
@export var cam : Camera3D
|
|
|
|
func _ready() -> void:
|
|
if spring_arm == null or cam == null:
|
|
push_error("CameraHolder : assigne spring_arm et cam dans l'inspecteur.")
|
|
return
|
|
#set fov, capture mouse cursor, and enable camera
|
|
cam.fov = fov_val
|
|
#Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
|
Input.set_use_accumulated_input(false)
|
|
set_active(active)
|
|
|
|
func set_active(state : bool) -> void:
|
|
#enable/disable play char camera
|
|
active = state
|
|
set_process_input(active)
|
|
set_process(active)
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if event is InputEventMouseMotion:
|
|
if has_lock_target(): return
|
|
var viewport_transform: Transform2D = get_tree().root.get_final_transform()
|
|
var mouse_motion = event.xformed_by(viewport_transform).relative
|
|
rotate_from_vector(mouse_motion * mouse_sensibility)
|
|
|
|
if event is InputEventMouseMotion:
|
|
var viewport_transform: Transform2D = get_tree().root.get_final_transform()
|
|
var mouse_motion = event.xformed_by(viewport_transform).relative
|
|
rotate_from_vector(mouse_motion * mouse_sensibility)
|
|
|
|
func _process(delta: float) -> void:
|
|
#position the cam according to its mode (default, aim (with left or right side))
|
|
var target_offset : Vector3 = Vector3.ZERO
|
|
var target_mult : float = 1.0
|
|
if cam_aimed:
|
|
var side : float = 1.0 if aim_cam_pos_side else -1.0 #true = droite, false = gauche
|
|
target_offset = Vector3(aim_cam_pos.x * side, aim_cam_pos.y, aim_cam_pos.z)
|
|
target_mult = aim_distance_multiplier
|
|
|
|
var weight : float = clampf(aim_cam_transition_speed * delta, 0.0, 1.0)
|
|
cam_offset = cam_offset.lerp(target_offset, weight)
|
|
cam_distance_mult = lerpf(cam_distance_mult, target_mult, weight)
|
|
|
|
var distance : float = maxf(spring_arm.get_hit_length() * cam_distance_mult + cam_offset.z, min_cam_distance)
|
|
cam.position = Vector3(cam_offset.x, cam_offset.y, distance)
|
|
|
|
if has_lock_target():
|
|
lock_on_handling(delta)
|
|
else:
|
|
if player_input: rotate_from_vector(player_input.read_look_vector() * joystick_sensibility)
|
|
|
|
#handle zoom
|
|
zoom_handling(delta)
|
|
|
|
func rotate_from_vector(vector : Vector2) -> void:
|
|
#rotate cam by the vector's amount, and clamp the rotation between max up and max down values
|
|
#(to avoid doing 360 degree turn with the cam for example)
|
|
if vector.length() == 0: return
|
|
rotation.y -= vector.x
|
|
rotation.x -= vector.y
|
|
rotation.x = clamp(rotation.x, deg_to_rad(min_limit_x), deg_to_rad(max_limit_x))
|
|
|
|
func zoom_handling(delta : float) -> void:
|
|
#zoom in/out cam, and clamp zoom value between min and max zoom values
|
|
if player_input: spring_arm.spring_length += player_input.read_zoom_axis() * zoom_speed * delta
|
|
spring_arm.spring_length = clamp(spring_arm.spring_length, min_spring_length, max_spring_length)
|
|
|
|
func switch_aim_side() -> void:
|
|
aim_cam_pos_side = !aim_cam_pos_side
|
|
|
|
func has_lock_target() -> bool:
|
|
return is_instance_valid(lock_target)
|
|
|
|
func lock_on_handling(delta : float) -> void:
|
|
#tourne progressivement la camera vers la cible verrouillee
|
|
var to_target : Vector3 = lock_target.global_position - global_position
|
|
var flat_dist : float = Vector2(to_target.x, to_target.z).length()
|
|
if flat_dist < 0.01: return
|
|
|
|
var target_yaw : float = atan2(-to_target.x, -to_target.z)
|
|
var target_pitch : float = clampf(atan2(to_target.y, flat_dist), deg_to_rad(min_limit_x), deg_to_rad(max_limit_x))
|
|
|
|
var weight : float = clampf(lock_on_speed * delta, 0.0, 1.0)
|
|
rotation.y = lerp_angle(rotation.y, target_yaw, weight)
|
|
rotation.x = lerp_angle(rotation.x, target_pitch, weight)
|
|
|
|
func set_lock_target(t : Node3D) -> void:
|
|
lock_target = t
|