This commit is contained in:
E250429F
2026-09-17 23:19:43 +02:00
parent 025a866eef
commit 3e857fa9f3
281 changed files with 38006 additions and 970 deletions
+34 -29
View File
@@ -3,15 +3,15 @@ extends SpringArm3D
@onready var player: CharacterBody3D = $"../.."
# --- Paramètres de mouvement ---
@export var max_follow_speed: float = 3.0
@export var speed_acceleration: float = 2.0
@export var max_follow_speed: float = 3
@export var speed_acceleration: float = 2.5
@export var height_offset: float = 2.5
@export var wait_time: float = 0.5
# --- Paramètres de Dialogue ---
@export var dialog_zoom_length: float = 2.0
@export var dialog_side_offset: float = 1.0
@export var transition_speed: float = 4.0 # Gère la vitesse du zoom, du décalage ET de la rotation en dialog
@export var dialog_zoom_length: float = 3.5
@export var dialog_side_offset: float = 2.0
@export var transition_speed: float = 4.0
@onready var normal_spring_length: float = spring_length
@@ -21,25 +21,26 @@ var current_side_offset: float = 0.0
var target_side_offset: float = 0.0
var is_in_dialog: bool = false
# Variables pour le dialogue
var dialog_target_position: Vector3 = Vector3.ZERO
var target_dialog_rotation_y: float = 0.0
var dialog_weight: float = 0.0 # Permet une transition ultra-fluide (0.0 = Exploration, 1.0 = Dialogue)
func _ready() -> void:
top_level = true
func set_dialog_mode(npc_position: Vector3 = Vector3.ZERO, force_pos=-1) -> void:
func set_dialog_mode(npc_position: Vector3 = Vector3.ZERO) -> void:
is_in_dialog = !is_in_dialog
if is_in_dialog:
var direction_to_npc = (npc_position - player.global_position).normalized()
var right_dot = global_transform.basis.x.dot(direction_to_npc)
dialog_target_position = npc_position
if right_dot >= 0 :
target_side_offset = dialog_side_offset
else:
target_side_offset = -dialog_side_offset
if force_pos == 0 :
target_side_offset = dialog_side_offset
elif force_pos == 1 :
target_side_offset = -dialog_side_offset
var dir_to_npc = (npc_position - player.global_position)
dir_to_npc.y = 0
dir_to_npc = dir_to_npc.normalized()
target_dialog_rotation_y = atan2(-dir_to_npc.x, -dir_to_npc.z)
target_side_offset = dialog_side_offset
else:
target_side_offset = 0.0
@@ -47,22 +48,23 @@ func _physics_process(delta: float) -> void:
if not is_instance_valid(player):
return
var target_rotation_y = player.global_rotation.y
# Mise à jour progressive du poids de transition du dialogue (de 0 à 1)
var target_weight = 1.0 if is_in_dialog else 0.0
dialog_weight = lerp(dialog_weight, target_weight, transition_speed * delta)
# ==========================================
# 1. GESTION DE LA ROTATION (Avant la position !)
# 1. GESTION DE LA ROTATION
# ==========================================
if is_in_dialog:
if is_in_dialog or dialog_weight > 0.01:
delay_timer = 0.3
current_follow_speed = 0.5
# La caméra tourne doucement pour se mettre dans le dos du joueur.
# On utilise transition_speed pour que ça se finisse en même temps que le zoom.
global_rotation.y = lerp_angle(global_rotation.y, target_rotation_y, transition_speed * delta)
# On interpole la rotation vers l'angle de dialogue en utilisant le poids
global_rotation.y = lerp_angle(global_rotation.y, target_dialog_rotation_y, transition_speed * delta)
else:
if not is_in_dialog and dialog_weight <= 0.01:
var target_rotation_y = player.global_rotation.y
if player.can_play:
# Comportement normal d'exploration (Le vieux Zelda)
var angle_diff = abs(angle_difference(global_rotation.y, target_rotation_y))
if angle_diff > 0.02 and player.velocity.length() > 0.1:
@@ -77,15 +79,18 @@ func _physics_process(delta: float) -> void:
# ==========================================
# 2. GESTION DU ZOOM ET DU DECALAGE
# 2. GESTION DU ZOOM, DU DECALAGE ET DE LA POSITION
# ==========================================
var target_length = dialog_zoom_length if is_in_dialog else normal_spring_length
spring_length = lerp(spring_length, target_length, transition_speed * delta)
current_side_offset = lerp(current_side_offset, target_side_offset, transition_speed * delta)
# On récupère le vecteur "Droite" MAINTENANT, car la rotation vient juste d'être mise à jour au-dessus.
var right_direction = global_transform.basis.x
# On applique la position finale (Joueur + Hauteur + Décalage latéral)
global_position = player.global_position + Vector3(0, height_offset, 0) + (right_direction * current_side_offset)
# Transition fluide du point de pivot (de la position du joueur vers le point intermédiaire du dialogue)
var normal_base = player.global_position
var dialog_base = player.global_position.lerp(dialog_target_position, 0.3)
var current_base = normal_base.lerp(dialog_base, dialog_weight)
global_position = current_base + Vector3(0, height_offset, 0) + (right_direction * current_side_offset)