Add Procedural Map
This commit is contained in:
@@ -8,6 +8,10 @@ extends Path3D
|
||||
@export var larghezza_binari: float = 1.2
|
||||
@export var gruppo_camere: Node3D
|
||||
|
||||
@export_group("Costruzione Rotaie")
|
||||
@export var distanza_traversine: float = 1.0
|
||||
@export var modello_traversina: PackedScene
|
||||
|
||||
@export_group("Controlli Manuali")
|
||||
@export var velocita_max: float = 15.0
|
||||
@export var velocita_min: float = -5.0
|
||||
@@ -32,10 +36,6 @@ var colori_fuochi: Array[Color] = [
|
||||
@export_group("Movimento e Oscillazione")
|
||||
@export_range(0.0, 1.0) var intensita_oscillazione_base: float = 0.5
|
||||
|
||||
@export_group("Costruzione Rotaie")
|
||||
@export var distanza_traversine: float = 1.0
|
||||
@export var modello_traversina: PackedScene
|
||||
|
||||
var treno_istanziato: Node3D
|
||||
var progresso_treno: float = 0.0
|
||||
var tempo_oscillazione: float = 0.0
|
||||
@@ -56,6 +56,63 @@ func _ready() -> void:
|
||||
else:
|
||||
print("ATTENZIONE: Devi prima disegnare i punti del Path3D!")
|
||||
|
||||
func _costruisci_rotaie_da_zero() -> void:
|
||||
var mat_legno = StandardMaterial3D.new()
|
||||
mat_legno.albedo_color = Color(0.35, 0.2, 0.1)
|
||||
var mat_ferro = StandardMaterial3D.new()
|
||||
mat_ferro.albedo_color = Color(0.6, 0.6, 0.65)
|
||||
mat_ferro.metallic = 0.8
|
||||
|
||||
var mesh_traversina_default = BoxMesh.new()
|
||||
mesh_traversina_default.size = Vector3(larghezza_binari + 0.6, 0.1, 0.3)
|
||||
var mesh_binario = BoxMesh.new()
|
||||
mesh_binario.size = Vector3(0.1, 0.15, distanza_traversine + 0.05)
|
||||
|
||||
var lunghezza_totale = curve.get_baked_length()
|
||||
var numero_pezzi = int(lunghezza_totale / distanza_traversine)
|
||||
|
||||
for i in range(numero_pezzi):
|
||||
var distanza = i * distanza_traversine
|
||||
var pezzo_binario = Node3D.new()
|
||||
add_child(pezzo_binario)
|
||||
|
||||
var pos_attuale_locale = curve.sample_baked(distanza, true)
|
||||
var distanza_avanti = distanza + 0.1
|
||||
var pos_avanti_locale = Vector3.ZERO
|
||||
|
||||
if distanza_avanti > lunghezza_totale:
|
||||
var pos_dietro = curve.sample_baked(distanza - 0.1, true)
|
||||
pos_avanti_locale = pos_attuale_locale + (pos_attuale_locale - pos_dietro)
|
||||
else:
|
||||
pos_avanti_locale = curve.sample_baked(distanza_avanti, true)
|
||||
|
||||
pezzo_binario.position = pos_attuale_locale
|
||||
var globale_attuale = to_global(pos_attuale_locale)
|
||||
var globale_avanti = to_global(pos_avanti_locale)
|
||||
if globale_attuale.distance_to(globale_avanti) > 0.001:
|
||||
pezzo_binario.look_at(globale_avanti, Vector3.UP)
|
||||
|
||||
if modello_traversina != null:
|
||||
var traversina_custom = modello_traversina.instantiate()
|
||||
pezzo_binario.add_child(traversina_custom)
|
||||
else:
|
||||
var traversina = MeshInstance3D.new()
|
||||
traversina.mesh = mesh_traversina_default
|
||||
traversina.material_override = mat_legno
|
||||
pezzo_binario.add_child(traversina)
|
||||
|
||||
var binario_sx = MeshInstance3D.new()
|
||||
binario_sx.mesh = mesh_binario
|
||||
binario_sx.material_override = mat_ferro
|
||||
binario_sx.position = Vector3(-larghezza_binari / 2.0, 0.1, 0)
|
||||
pezzo_binario.add_child(binario_sx)
|
||||
|
||||
var binario_dx = MeshInstance3D.new()
|
||||
binario_dx.mesh = mesh_binario
|
||||
binario_dx.material_override = mat_ferro
|
||||
binario_dx.position = Vector3(larghezza_binari / 2.0, 0.1, 0)
|
||||
pezzo_binario.add_child(binario_dx)
|
||||
|
||||
func _calcola_fermate() -> void:
|
||||
var fermate_temp = []
|
||||
for figlio in get_children():
|
||||
@@ -88,10 +145,8 @@ func _test_fuochi_manuale() -> void:
|
||||
|
||||
var offset_x = randf_range(-6.0, 6.0)
|
||||
var offset_z = randf_range(-6.0, 6.0)
|
||||
# 1. POSIZIONA
|
||||
fuoco_root.global_position = treno_istanziato.global_position + Vector3(offset_x, 0.5, offset_z)
|
||||
|
||||
# 2. COLORA E ACCENDI
|
||||
if fuoco_root.has_method("imposta_colore"):
|
||||
fuoco_root.imposta_colore(colori_fuochi.pick_random())
|
||||
if fuoco_root.has_method("accendi"):
|
||||
@@ -156,23 +211,24 @@ func _gestione_movimento_treno(delta: float) -> void:
|
||||
progresso_treno += lunghezza_totale
|
||||
if offsets_fermate.size() > 0: indice_prossima_fermata = offsets_fermate.size() - 1
|
||||
|
||||
# 1. Il centro matematico perfetto e incontrovertibile del treno
|
||||
var pos_centro = to_global(curve.sample_baked(progresso_treno, true))
|
||||
|
||||
# 2. Il punto in cui deve guardare (abbastanza lontano per non vibrare)
|
||||
var prog_davanti = wrapf(progresso_treno + 2.0, 0.0, lunghezza_totale)
|
||||
var pos_davanti = to_global(curve.sample_baked(prog_davanti, true))
|
||||
|
||||
if pos_centro.distance_to(pos_davanti) > 0.01:
|
||||
# Posizionamento esatto, zero vibrazioni laterali
|
||||
treno_istanziato.global_position = pos_centro
|
||||
treno_istanziato.look_at(pos_davanti, Vector3.UP)
|
||||
treno_istanziato.rotate_y(PI)
|
||||
|
||||
if gruppo_camere:
|
||||
# La telecamera segue il punto perfetto
|
||||
gruppo_camere.global_position = gruppo_camere.global_position.lerp(pos_centro, delta * 12.0)
|
||||
|
||||
|
||||
# Usiamo orthonormalized() per pulire le micro-imperfezioni matematiche
|
||||
var rot_cam = gruppo_camere.global_basis.orthonormalized().get_rotation_quaternion()
|
||||
var rot_treno = treno_istanziato.global_basis.orthonormalized().get_rotation_quaternion()
|
||||
|
||||
gruppo_camere.global_basis = Basis(rot_cam.slerp(rot_treno, delta * 8.0))
|
||||
|
||||
if not fermata_in_corso:
|
||||
var vel_reale = abs(velocita_treno * moltiplicatore_stazione)
|
||||
tempo_oscillazione += delta * vel_reale * 2.0
|
||||
@@ -206,10 +262,8 @@ func _esegui_fermata(andando_avanti: bool = true) -> void:
|
||||
var offset_x = randf_range(-5.0, 5.0)
|
||||
var offset_z = randf_range(-5.0, 5.0)
|
||||
|
||||
# 1. POSIZIONA
|
||||
fuoco_root.global_position = posizione_marker + Vector3(offset_x, 0.5, offset_z)
|
||||
|
||||
# 2. COLORA E ACCENDI
|
||||
if fuoco_root.has_method("imposta_colore"):
|
||||
fuoco_root.imposta_colore(colori_fuochi.pick_random())
|
||||
if fuoco_root.has_method("accendi"):
|
||||
@@ -230,63 +284,6 @@ func _esegui_fermata(andando_avanti: bool = true) -> void:
|
||||
tween_ripartenza.tween_property(self, "moltiplicatore_stazione", 1.0, tempo_ripartenza)
|
||||
tween_ripartenza.tween_callback(func(): in_ripartenza = false)
|
||||
|
||||
func _costruisci_rotaie_da_zero() -> void:
|
||||
var mat_legno = StandardMaterial3D.new()
|
||||
mat_legno.albedo_color = Color(0.35, 0.2, 0.1)
|
||||
var mat_ferro = StandardMaterial3D.new()
|
||||
mat_ferro.albedo_color = Color(0.6, 0.6, 0.65)
|
||||
mat_ferro.metallic = 0.8
|
||||
|
||||
var mesh_traversina_default = BoxMesh.new()
|
||||
mesh_traversina_default.size = Vector3(larghezza_binari + 0.6, 0.1, 0.3)
|
||||
var mesh_binario = BoxMesh.new()
|
||||
mesh_binario.size = Vector3(0.1, 0.15, distanza_traversine + 0.05)
|
||||
|
||||
var lunghezza_totale = curve.get_baked_length()
|
||||
var numero_pezzi = int(lunghezza_totale / distanza_traversine)
|
||||
|
||||
for i in range(numero_pezzi):
|
||||
var distanza = i * distanza_traversine
|
||||
var pezzo_binario = Node3D.new()
|
||||
add_child(pezzo_binario)
|
||||
|
||||
var pos_attuale_locale = curve.sample_baked(distanza, true)
|
||||
var distanza_avanti = distanza + 0.1
|
||||
var pos_avanti_locale = Vector3.ZERO
|
||||
|
||||
if distanza_avanti > lunghezza_totale:
|
||||
var pos_dietro = curve.sample_baked(distanza - 0.1, true)
|
||||
pos_avanti_locale = pos_attuale_locale + (pos_attuale_locale - pos_dietro)
|
||||
else:
|
||||
pos_avanti_locale = curve.sample_baked(distanza_avanti, true)
|
||||
|
||||
pezzo_binario.position = pos_attuale_locale
|
||||
var globale_attuale = to_global(pos_attuale_locale)
|
||||
var globale_avanti = to_global(pos_avanti_locale)
|
||||
if globale_attuale.distance_to(globale_avanti) > 0.001:
|
||||
pezzo_binario.look_at(globale_avanti, Vector3.UP)
|
||||
|
||||
if modello_traversina != null:
|
||||
var traversina_custom = modello_traversina.instantiate()
|
||||
pezzo_binario.add_child(traversina_custom)
|
||||
else:
|
||||
var traversina = MeshInstance3D.new()
|
||||
traversina.mesh = mesh_traversina_default
|
||||
traversina.material_override = mat_legno
|
||||
pezzo_binario.add_child(traversina)
|
||||
|
||||
var binario_sx = MeshInstance3D.new()
|
||||
binario_sx.mesh = mesh_binario
|
||||
binario_sx.material_override = mat_ferro
|
||||
binario_sx.position = Vector3(-larghezza_binari / 2.0, 0.1, 0)
|
||||
pezzo_binario.add_child(binario_sx)
|
||||
|
||||
var binario_dx = MeshInstance3D.new()
|
||||
binario_dx.mesh = mesh_binario
|
||||
binario_dx.material_override = mat_ferro
|
||||
binario_dx.position = Vector3(larghezza_binari / 2.0, 0.1, 0)
|
||||
pezzo_binario.add_child(binario_dx)
|
||||
|
||||
func _costruisci_treno() -> void:
|
||||
if modello_treno != null:
|
||||
treno_istanziato = modello_treno.instantiate()
|
||||
|
||||
@@ -2,17 +2,18 @@ extends Node3D
|
||||
|
||||
@export_group("Riferimenti Camere")
|
||||
@export var camera_iso : Camera3D
|
||||
@export var pivot_iso : Node3D # <-- NUOVO: Trascina qui il nodo PivotIso!
|
||||
@export var camera_frontale : Camera3D
|
||||
@export var camera_laterale : Camera3D
|
||||
@export var camera_laterale_2 : Camera3D # Nuova Camera 4
|
||||
@export var camera_alta : Camera3D # Nuova Camera 5
|
||||
@export var camera_laterale_2 : Camera3D
|
||||
@export var camera_alta : Camera3D
|
||||
|
||||
@export_group("Movimento Camera 1")
|
||||
@export var move_speed : float = 20.0
|
||||
@export var rotation_speed : float = 0.2
|
||||
|
||||
@export_group("Cinematic Mode")
|
||||
@export var tempo_cambio_camera : float = 10.0 # Quanti secondi dura ogni inquadratura
|
||||
@export var tempo_cambio_camera : float = 10.0
|
||||
|
||||
var is_moving_enabled : bool = true
|
||||
|
||||
@@ -22,28 +23,38 @@ var cinematic_timer : float = 0.0
|
||||
var cinematic_index : int = 0
|
||||
var array_camere : Array[Camera3D] = []
|
||||
|
||||
# --- Variabile per il Reset ---
|
||||
var transform_iniziale_pivot : Transform3D
|
||||
|
||||
func _ready():
|
||||
# Creiamo un array con le telecamere valide per ciclarle facilmente
|
||||
# Salviamo la posizione e rotazione del PIVOT, non della camera!
|
||||
if pivot_iso:
|
||||
transform_iniziale_pivot = pivot_iso.transform
|
||||
|
||||
if camera_iso: array_camere.append(camera_iso)
|
||||
if camera_frontale: array_camere.append(camera_frontale)
|
||||
if camera_laterale: array_camere.append(camera_laterale)
|
||||
if camera_laterale_2: array_camere.append(camera_laterale_2)
|
||||
if camera_alta: array_camere.append(camera_alta)
|
||||
|
||||
# All'inizio, assicuriamoci che la CameraIso sia quella attiva
|
||||
if camera_iso:
|
||||
camera_iso.make_current()
|
||||
|
||||
func _input(event):
|
||||
# Cambio Camera Manuale e Cinematic Toggle
|
||||
if event is InputEventKey and event.pressed and not event.echo:
|
||||
|
||||
# --- TASTO R: RESET DELLA CAMERA ISOMETRICA ---
|
||||
if event.keycode == KEY_R and is_moving_enabled and pivot_iso:
|
||||
# Riporta il Pivot al centro esatto sopra il treno
|
||||
pivot_iso.transform = transform_iniziale_pivot
|
||||
print("Camera Isometrica resettata!")
|
||||
return
|
||||
|
||||
# --- TASTO C: TOGGLE CINEMATIC MODE ---
|
||||
if event.keycode == KEY_C:
|
||||
is_cinematic_mode = !is_cinematic_mode
|
||||
if is_cinematic_mode:
|
||||
cinematic_timer = 0.0 # Azzera il timer
|
||||
# Cerca qual è la camera attualmente attiva per iniziare il ciclo da lì
|
||||
cinematic_timer = 0.0
|
||||
for i in range(array_camere.size()):
|
||||
if array_camere[i].current:
|
||||
cinematic_index = i
|
||||
@@ -51,7 +62,7 @@ func _input(event):
|
||||
print("Cinematic Mode: ATTIVATA")
|
||||
else:
|
||||
print("Cinematic Mode: DISATTIVATA")
|
||||
return # Usciamo per non eseguire altri controlli in questo frame
|
||||
return
|
||||
|
||||
# --- CONTROLLI MANUALI (1-5) ---
|
||||
var intervento_manuale = false
|
||||
@@ -81,34 +92,28 @@ func _input(event):
|
||||
is_moving_enabled = false
|
||||
intervento_manuale = true
|
||||
|
||||
# Se l'utente preme un numero per cambiare camera manualmente, spegni la cinematic mode
|
||||
if intervento_manuale and is_cinematic_mode:
|
||||
is_cinematic_mode = false
|
||||
print("Cinematic Mode: DISATTIVATA (Intervento manuale)")
|
||||
|
||||
# Rotazione: Solo se il movimento è abilitato (Camera 1)
|
||||
if is_moving_enabled:
|
||||
# --- ROTAZIONE MOUSE (Applicata al PIVOT!) ---
|
||||
if is_moving_enabled and pivot_iso:
|
||||
if event is InputEventMouseMotion and Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
||||
rotate_y(deg_to_rad(-event.relative.x * rotation_speed))
|
||||
# Ruotando il pivot, la camera farà una bellissima orbita circolare!
|
||||
pivot_iso.rotate_y(deg_to_rad(-event.relative.x * rotation_speed))
|
||||
|
||||
func _process(delta):
|
||||
# --- LOGICA CINEMATIC MODE ---
|
||||
if is_cinematic_mode and array_camere.size() > 0:
|
||||
cinematic_timer += delta
|
||||
if cinematic_timer >= tempo_cambio_camera:
|
||||
cinematic_timer = 0.0
|
||||
# Passa alla camera successiva e se è l'ultima ricomincia da zero
|
||||
cinematic_index = (cinematic_index + 1) % array_camere.size()
|
||||
|
||||
var next_cam = array_camere[cinematic_index]
|
||||
next_cam.make_current()
|
||||
|
||||
# Abilita il movimento WASD solo se la camera inquadrata è quella isometrica (la 1)
|
||||
is_moving_enabled = (next_cam == camera_iso)
|
||||
|
||||
# --- LOGICA DI MOVIMENTO WASD ---
|
||||
# Se siamo in camera 2, 3, 4 o 5, non processare il movimento WASD
|
||||
if not is_moving_enabled:
|
||||
# --- LOGICA DI MOVIMENTO WASD (Applicata al PIVOT!) ---
|
||||
if not is_moving_enabled or pivot_iso == null:
|
||||
return
|
||||
|
||||
var input_dir = Vector3.ZERO
|
||||
@@ -119,9 +124,17 @@ func _process(delta):
|
||||
|
||||
if input_dir != Vector3.ZERO:
|
||||
input_dir = input_dir.normalized()
|
||||
var forward = transform.basis.z
|
||||
var right = transform.basis.x
|
||||
|
||||
# Prendiamo le direzioni dal Pivot, così WASD segue dove stiamo guardando
|
||||
var forward = pivot_iso.transform.basis.z
|
||||
var right = pivot_iso.transform.basis.x
|
||||
forward.y = 0
|
||||
right.y = 0
|
||||
var motion = (forward * input_dir.z + right * input_dir.x).normalized()
|
||||
position += motion * move_speed * delta
|
||||
|
||||
forward = forward.normalized()
|
||||
right = right.normalized()
|
||||
|
||||
var motion = (forward * input_dir.z + right * input_dir.x)
|
||||
|
||||
# Muoviamo il centro dell'orbita (il Pivot)
|
||||
pivot_iso.position += motion * move_speed * delta
|
||||
|
||||
Reference in New Issue
Block a user