add wagons
This commit is contained in:
@@ -1,31 +1,60 @@
|
||||
extends Path3D
|
||||
|
||||
@export_group("Train")
|
||||
@export var train_speed: float = 6.0
|
||||
@export var is_inmotion: bool = true
|
||||
@export var train_model: PackedScene
|
||||
##train speed
|
||||
@export var train_speed: float = 6.0
|
||||
##if true the train is in motion
|
||||
@export var is_inmotion: bool = true
|
||||
##the model for the locomotive
|
||||
@export var train_model: PackedScene
|
||||
##array of wagon scenes
|
||||
@export var wagon_pool: Resource
|
||||
##if true the number of wagons is random from 1 to wagon_count
|
||||
@export var wagon_random_number: bool = true
|
||||
##if wagon_random_number = true is used as max wagons
|
||||
@export_range(0, 32, 1, "or_greater") var wagon_count: int = 3
|
||||
##the distance between two wagons
|
||||
@export var wagon_gap: float = 0.4
|
||||
##the scale to calculate the distance of the bounds
|
||||
@export_range(0.1, 2.0, 0.05, "or_greater") var wagon_spacing_scale: float = 0.5
|
||||
##override spacing using this value
|
||||
@export var wagon_spacing_override: float = 0.0
|
||||
##distance of the rail axes
|
||||
@export var axes_distance: float = 3.0
|
||||
@export var rail_distance: float = 1.2
|
||||
##discance between rails
|
||||
@export var rail_distance: float = 1.2
|
||||
##current camera
|
||||
@export var cameras: Node3D
|
||||
##swing of the train during the ran
|
||||
@export_range(0.0, 1.0) var basic_swing: float = 0.1
|
||||
|
||||
@export_group("Rails Bulding")
|
||||
##distance between sleepers of the rails
|
||||
@export var sleepers_distance: float = 1.0
|
||||
##nodel for the sleeper of the rail
|
||||
@export var sleepers_model: PackedScene
|
||||
|
||||
@export_group("Manual Controls")
|
||||
##max speed
|
||||
@export var speed_max: float = 15.0
|
||||
@export var speed_min: float = -5.0
|
||||
##min speed
|
||||
@export var speed_min: float = -5.0
|
||||
##acceleration
|
||||
@export var manual_acceleration: float = 5.0
|
||||
|
||||
@export_group("Train Stops")
|
||||
##if true the train stop the ran on stops
|
||||
@export var enable_stops: bool = true
|
||||
##time of stop
|
||||
@export var stop_time: float = 4.0
|
||||
@export var brake_distance: float = 15.0
|
||||
##distance when the train start to brake
|
||||
@export var brake_distance: float = 15.0
|
||||
##restart time
|
||||
@export var restart_time: float = 3.0
|
||||
##scene for fireworks
|
||||
@export var fireworks_scene: PackedScene
|
||||
|
||||
var fireworks_colors: Array[Color] = [
|
||||
##array of colors for fireworks
|
||||
@export var fireworks_colors: Array[Color] = [
|
||||
Color(1.0, 0.2, 0.2), # Rosso vivo
|
||||
Color(0.2, 1.0, 0.2), # Verde lime
|
||||
Color(0.3, 0.5, 1.0), # Blu cielo
|
||||
@@ -48,9 +77,14 @@ var stop_multiply: float = 1.0
|
||||
var is_restarting: bool = false
|
||||
var tween_restart: Tween
|
||||
var environment_config: EnvironmentConfig
|
||||
var wagon_instances: Array[Node3D] = []
|
||||
var wagon_progress_offsets: Array[float] = []
|
||||
|
||||
func _ready() -> void:
|
||||
randomize()
|
||||
|
||||
_cache_environment_config()
|
||||
|
||||
if curve != null and curve.get_baked_length() > 0:
|
||||
build_rails()
|
||||
build_train()
|
||||
@@ -153,6 +187,8 @@ func _snap_train_to_progress() -> void:
|
||||
cameras.global_position = center_position
|
||||
cameras.global_basis = train_instance.global_basis
|
||||
|
||||
_snap_wagons_to_progress(total_length)
|
||||
|
||||
func build_rails() -> void:
|
||||
var mat_wood = StandardMaterial3D.new()
|
||||
mat_wood.albedo_color = Color(0.35, 0.2, 0.1)
|
||||
@@ -323,6 +359,8 @@ func train_move(delta: float) -> void:
|
||||
if cameras:
|
||||
cameras.global_position = center_position
|
||||
cameras.global_basis = train_instance.global_basis
|
||||
|
||||
_snap_wagons_to_progress(total_length)
|
||||
|
||||
var real_speed = abs(train_speed * stop_multiply)
|
||||
var speed_factor = clamp(real_speed / max(speed_max, 0.001), 0.0, 1.0)
|
||||
@@ -401,6 +439,34 @@ func build_train() -> void:
|
||||
else:
|
||||
build_default_train()
|
||||
|
||||
var wagons = wagon_count
|
||||
if wagon_random_number:
|
||||
wagons = randi_range(1, wagon_count)
|
||||
build_train_wagons(wagons)
|
||||
|
||||
func build_train_wagons(wagon_number: int) -> void:
|
||||
_clear_train_wagons()
|
||||
if wagon_number <= 0 or wagon_pool == null or not "available_wagons" in wagon_pool:
|
||||
return
|
||||
if wagon_pool.available_wagons.is_empty():
|
||||
return
|
||||
|
||||
for i in range(wagon_number):
|
||||
var wagon_scene: PackedScene = wagon_pool.available_wagons.pick_random()
|
||||
if wagon_scene == null:
|
||||
continue
|
||||
|
||||
var wagon: Node3D = wagon_scene.instantiate() as Node3D
|
||||
if wagon == null:
|
||||
push_warning("Wagon scene root must be a Node3D.")
|
||||
continue
|
||||
|
||||
add_child(wagon)
|
||||
wagon_instances.append(wagon)
|
||||
|
||||
_update_wagon_progress_offsets()
|
||||
_snap_wagons_to_progress()
|
||||
|
||||
func build_default_train() -> void:
|
||||
train_instance = Node3D.new()
|
||||
add_child(train_instance)
|
||||
@@ -435,3 +501,118 @@ func build_default_train() -> void:
|
||||
stack.material_override = mat_body
|
||||
stack.position = Vector3(0, 1.2, 1.0)
|
||||
train_instance.add_child(stack)
|
||||
|
||||
func _clear_train_wagons() -> void:
|
||||
for wagon in wagon_instances:
|
||||
if is_instance_valid(wagon):
|
||||
wagon.queue_free()
|
||||
wagon_instances.clear()
|
||||
wagon_progress_offsets.clear()
|
||||
|
||||
func _update_wagon_progress_offsets() -> void:
|
||||
wagon_progress_offsets.clear()
|
||||
if train_instance == null or wagon_instances.is_empty():
|
||||
return
|
||||
|
||||
var train_length: float = _get_vehicle_length(train_instance)
|
||||
var previous_length: float = train_length
|
||||
var accumulated_distance: float = 0.0
|
||||
|
||||
for wagon in wagon_instances:
|
||||
var wagon_length: float = _get_vehicle_length(wagon)
|
||||
accumulated_distance += _get_wagon_spacing(previous_length, wagon_length)
|
||||
wagon_progress_offsets.append(accumulated_distance)
|
||||
previous_length = wagon_length
|
||||
|
||||
func _get_wagon_spacing(previous_length: float, wagon_length: float) -> float:
|
||||
if wagon_spacing_override > 0.0:
|
||||
return wagon_spacing_override + wagon_gap
|
||||
|
||||
var detected_spacing: float = previous_length * 0.5 + wagon_length * 0.5
|
||||
return detected_spacing * wagon_spacing_scale + wagon_gap
|
||||
|
||||
func _snap_wagons_to_progress(total_length: float = 0.0) -> void:
|
||||
if curve == null or wagon_instances.is_empty():
|
||||
return
|
||||
|
||||
if total_length <= 0.0:
|
||||
total_length = curve.get_baked_length()
|
||||
if total_length <= 0.0:
|
||||
return
|
||||
|
||||
var direction: float = 1.0
|
||||
if train_speed < 0.0:
|
||||
direction = -1.0
|
||||
|
||||
for i in range(wagon_instances.size()):
|
||||
var wagon: Node3D = wagon_instances[i]
|
||||
if not is_instance_valid(wagon):
|
||||
continue
|
||||
|
||||
var wagon_offset: float = float(i + 1) * 7.0
|
||||
if i < wagon_progress_offsets.size():
|
||||
wagon_offset = wagon_progress_offsets[i]
|
||||
|
||||
var wagon_progress: float = train_progress - direction * wagon_offset
|
||||
_snap_vehicle_to_progress(wagon, wagon_progress, total_length)
|
||||
|
||||
func _snap_vehicle_to_progress(vehicle: Node3D, progress: float, total_length: float) -> void:
|
||||
var vehicle_progress: float = wrapf(progress, 0.0, total_length)
|
||||
var center_position: Vector3 = to_global(curve.sample_baked(vehicle_progress, true))
|
||||
var prog_forward: float = wrapf(vehicle_progress + 2.0, 0.0, total_length)
|
||||
var forward_position: Vector3 = to_global(curve.sample_baked(prog_forward, true))
|
||||
|
||||
vehicle.global_position = center_position
|
||||
if center_position.distance_to(forward_position) > 0.01:
|
||||
vehicle.look_at(forward_position, Vector3.UP)
|
||||
vehicle.rotate_y(PI)
|
||||
|
||||
func _get_vehicle_length(vehicle: Node3D) -> float:
|
||||
var bounds: AABB = _get_node_local_bounds(vehicle, vehicle)
|
||||
if bounds.size == Vector3.ZERO:
|
||||
return 7.0
|
||||
|
||||
return maxf(bounds.size.z, 0.1)
|
||||
|
||||
func _get_node_local_bounds(root: Node3D, node: Node) -> AABB:
|
||||
var result: AABB = AABB()
|
||||
var has_bounds: bool = false
|
||||
|
||||
var mesh_instance := node as MeshInstance3D
|
||||
if mesh_instance != null and mesh_instance.mesh != null:
|
||||
var mesh_bounds: AABB = mesh_instance.get_aabb()
|
||||
var mesh_transform: Transform3D = root.global_transform.affine_inverse() * mesh_instance.global_transform
|
||||
for corner in _get_aabb_corners(mesh_bounds):
|
||||
var local_point: Vector3 = mesh_transform * corner
|
||||
if has_bounds:
|
||||
result = result.expand(local_point)
|
||||
else:
|
||||
result = AABB(local_point, Vector3.ZERO)
|
||||
has_bounds = true
|
||||
|
||||
for child in node.get_children():
|
||||
var child_bounds: AABB = _get_node_local_bounds(root, child)
|
||||
if child_bounds.size == Vector3.ZERO:
|
||||
continue
|
||||
|
||||
if has_bounds:
|
||||
result = result.merge(child_bounds)
|
||||
else:
|
||||
result = child_bounds
|
||||
has_bounds = true
|
||||
|
||||
return result
|
||||
|
||||
func _get_aabb_corners(bounds: AABB) -> Array[Vector3]:
|
||||
var start: Vector3 = bounds.position
|
||||
var end: Vector3 = bounds.end
|
||||
return [
|
||||
Vector3(start.x, start.y, start.z),
|
||||
Vector3(end.x, start.y, start.z),
|
||||
Vector3(start.x, end.y, start.z),
|
||||
Vector3(end.x, end.y, start.z),
|
||||
Vector3(start.x, start.y, end.z),
|
||||
Vector3(end.x, start.y, end.z),
|
||||
Vector3(start.x, end.y, end.z),
|
||||
Vector3(end.x, end.y, end.z),
|
||||
]
|
||||
|
||||
6
core/biome_generator/wagon_pool.gd
Normal file
6
core/biome_generator/wagon_pool.gd
Normal file
@@ -0,0 +1,6 @@
|
||||
## Resource that lists the wagon scenes available for train composition.
|
||||
class_name WagonPool
|
||||
extends Resource
|
||||
|
||||
@export var name: String = "New Wagon Pool"
|
||||
@export var available_wagons: Array[PackedScene] = []
|
||||
9
core/biome_generator/wagon_pool.tres
Normal file
9
core/biome_generator/wagon_pool.tres
Normal file
@@ -0,0 +1,9 @@
|
||||
[gd_resource type="Resource" script_class="WagonPool" format=3 uid="uid://bjnytgwt8tmf4"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://dvk3bytqn3m5s" path="res://tgcc/train/main_train.tscn" id="1_t6q5r"]
|
||||
[ext_resource type="Script" uid="uid://b6xk0gtn2pwa" path="res://core/biome_generator/wagon_pool.gd" id="2_x6bmc"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_x6bmc")
|
||||
name = "Wagon Pool"
|
||||
available_wagons = Array[PackedScene]([ExtResource("1_t6q5r")])
|
||||
@@ -23,6 +23,7 @@
|
||||
[ext_resource type="AudioStream" uid="uid://h5yhjn1x3f4j" path="res://core/daynight/sounds/rain_2.mp3" id="21_wnhyx"]
|
||||
[ext_resource type="AudioStream" uid="uid://elrjw0smm0cj" path="res://core/daynight/sounds/rain_3.mp3" id="22_53kbn"]
|
||||
[ext_resource type="Script" uid="uid://cx2tlvxhvatj5" path="res://docs/museums/daynight/control.gd" id="23_27ile"]
|
||||
[ext_resource type="Script" uid="uid://ccdd52apoh4ir" path="res://docs/museums/daynight/camera_3d.gd" id="24_sw7bt"]
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_wjpfq"]
|
||||
fractal_lacunarity = 1.915
|
||||
@@ -148,7 +149,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||
curve = SubResource("Curve3D_xtogr")
|
||||
script = ExtResource("6_pypsn")
|
||||
train_model = ExtResource("6_wjpfq")
|
||||
cameras = NodePath("../cameras")
|
||||
cameras = NodePath("../Camera3D")
|
||||
sleepers_model = ExtResource("8_mb5yv")
|
||||
fireworks_scene = ExtResource("8_xtogr")
|
||||
|
||||
@@ -373,6 +374,10 @@ theme_override_colors/font_color = Color(1, 1, 1, 1)
|
||||
theme_override_colors/font_outline_color = Color(1, 1, 1, 1)
|
||||
text = "Weather: Clear"
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="." unique_id=1305162994]
|
||||
transform = Transform3D(0.035881948, 0.7570504, -0.65237045, -0.1472942, 0.6496678, 0.7458125, 0.9884417, 0.06932917, 0.13482046, -18.173235, 14.658583, -10.483771)
|
||||
script = ExtResource("24_sw7bt")
|
||||
|
||||
[connection signal="toggled" from="Control/Snow" to="Control" method="_on_snow_toggled"]
|
||||
[connection signal="toggled" from="Control/Rain" to="Control" method="_on_rain_toggled"]
|
||||
[connection signal="toggled" from="Control/Wind" to="Control" method="_on_wind_toggled"]
|
||||
|
||||
71
export_presets.cfg
Normal file
71
export_presets.cfg
Normal file
@@ -0,0 +1,71 @@
|
||||
[preset.0]
|
||||
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path="../tgcc.exe"
|
||||
patches=PackedStringArray()
|
||||
patch_delta_encoding=false
|
||||
patch_delta_compression_level_zstd=19
|
||||
patch_delta_min_reduction=0.1
|
||||
patch_delta_include_filters="*"
|
||||
patch_delta_exclude_filters=""
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
seed=0
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
script_export_mode=2
|
||||
|
||||
[preset.0.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/s3tc_bptc=true
|
||||
texture_format/etc2_astc=false
|
||||
shader_baker/enabled=false
|
||||
binary_format/architecture="x86_64"
|
||||
codesign/enable=false
|
||||
codesign/timestamp=true
|
||||
codesign/timestamp_server_url=""
|
||||
codesign/digest_algorithm=1
|
||||
codesign/description=""
|
||||
codesign/custom_options=PackedStringArray()
|
||||
application/modify_resources=true
|
||||
application/icon=""
|
||||
application/console_wrapper_icon=""
|
||||
application/icon_interpolation=4
|
||||
application/file_version=""
|
||||
application/product_version=""
|
||||
application/company_name=""
|
||||
application/product_name=""
|
||||
application/file_description=""
|
||||
application/copyright=""
|
||||
application/trademarks=""
|
||||
application/export_angle=0
|
||||
application/export_d3d12=0
|
||||
application/d3d12_agility_sdk_multiarch=true
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
ssh_remote_deploy/extra_args_ssh=""
|
||||
ssh_remote_deploy/extra_args_scp=""
|
||||
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
|
||||
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
|
||||
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
|
||||
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
|
||||
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
|
||||
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
|
||||
Start-ScheduledTask -TaskName godot_remote_debug
|
||||
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
|
||||
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||
Remove-Item -Recurse -Force '{temp_dir}'"
|
||||
@@ -45,6 +45,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://1c1ion0qnho4" path="res://tgcc/map/map_1/map_1.tscn" id="43_ysd85"]
|
||||
[ext_resource type="Script" uid="uid://dboerd4a6dwj7" path="res://core/biome_generator/rails.gd" id="44_rcqo0"]
|
||||
[ext_resource type="PackedScene" uid="uid://dvk3bytqn3m5s" path="res://tgcc/train/main_train.tscn" id="45_c0jxs"]
|
||||
[ext_resource type="Resource" uid="uid://bjnytgwt8tmf4" path="res://core/biome_generator/wagon_pool.tres" id="46_exdk1"]
|
||||
[ext_resource type="PackedScene" uid="uid://0kgjaqijaqku" path="res://docs/museums/biome_generator/rails.tscn" id="46_lbmv2"]
|
||||
[ext_resource type="PackedScene" uid="uid://dn1btv0e0ses7" path="res://core/fireworks.tscn" id="47_q7p65"]
|
||||
[ext_resource type="Script" uid="uid://cx2tlvxhvatj5" path="res://docs/museums/daynight/control.gd" id="48_r5xyi"]
|
||||
@@ -195,6 +196,10 @@ transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 270,
|
||||
curve = SubResource("Curve3D_ndco5")
|
||||
script = ExtResource("44_rcqo0")
|
||||
train_model = ExtResource("45_c0jxs")
|
||||
wagon_pool = ExtResource("46_exdk1")
|
||||
wagon_count = 4
|
||||
wagon_gap = 0.5
|
||||
wagon_spacing_scale = 0.7999999999999999
|
||||
cameras = NodePath("../cameras")
|
||||
sleepers_model = ExtResource("46_lbmv2")
|
||||
fireworks_scene = ExtResource("47_q7p65")
|
||||
|
||||
Reference in New Issue
Block a user