Compare commits

...

6 Commits

35 changed files with 290 additions and 228 deletions

View File

@ -52,7 +52,9 @@ signal train_left(track : Dolly)
func _ready() -> void: func _ready() -> void:
reset() reset()
func set_line(line: StringName):
subway.set_line(line)
## One arrival and departure ## One arrival and departure
func cycle() -> void: func cycle() -> void:
await arrive() await arrive()

View File

@ -2,54 +2,56 @@ class_name Fahrplan extends Node3D
## easy graph: <station> : [Track1Train1 (next halt), Track1Train2], [Track2Train1(next halt), ...] ## easy graph: <station> : [Track1Train1 (next halt), Track1Train2], [Track2Train1(next halt), ...]
## CAVEAT: These must be direct children of the fahrplan! ## CAVEAT: These must be direct children of the fahrplan!
@onready var fahrplan : Dictionary[Node3D, Array] = { @onready var fahrplan : Dictionary[Station, Array] = {
$station_hirschfeld: [[$station_university_mensa, $station_parity_square],[]], $hirschfeld: [["u2", $uni_mensa, "u1", $parity_square],[]],
$station_hirschfeld : [[$station_university_mensa, $station_parity_square],[]], $uni_mensa : [["u2", $uni_main],[]],
$station_university_mensa : [[$station_university_main],[]], $uni_main: [["u2", $ministry],["u8", $rosenthal, "u2", $uni_mensa, "u1", $saint_exupery]],
$station_university_main: [[$station_ministry],[$station_rosenthal, $station_university_mensa]], $parity_square : [["u4", $saint_exupery, "u1", $saint_exupery], []],
$station_parity_square : [[$station_saint_exupery],[$station_rosenthal]], $saint_exupery : [["u4", $rosenthal], ["u1", $uni_main]],
$station_saint_exupery : [[$station_saint_exupery],[$station_rosenthal]],
$station_ministry : [null,null], # Endstation $ministry : [null, null], # Endstation
$station_rosenthal : [null,null], # Endstation $rosenthal : [null, null], # Endstation
} }
## List of all registered station nodes, used to unparent them ## List of all registered station nodes, used to unparent them
@onready var stations : Array[Node3D] = fahrplan.keys() @onready var stations : Array[Station] = fahrplan.keys()
@onready var tracks : Array[Dolly] = [%Track0Dolly, %Track1Dolly] @onready var tracks : Array[Dolly] = [%Track0Dolly, %Track1Dolly]
@export var empty_train_random_delay : Vector2 = Vector2(5.0, 20.0) @export var empty_train_random_delay : Vector2 = Vector2(5.0, 20.0)
func _set_signage_texts(group: StringName, message: String) -> void: func _set_signage_texts(group: StringName, message: String) -> void:
get_tree().call_group(group, "set_text", "") get_tree().set_group(group, "text", "")
for i in range(len(message)): for i in range(len(message)):
get_tree().call_group(group, "set_text", message.substr(0, i+1)) get_tree().set_group(group, "text", message.substr(0, i+1))
await get_tree().create_timer(0.05).timeout await get_tree().create_timer(0.05).timeout
func _ready() -> void: func _ready() -> void:
var x : Node3D = $station_hirschfeld
print(x.name)
await get_tree().process_frame await get_tree().process_frame
tracks[0].train_left.connect(_player_train_left) tracks[0].train_left.connect(_player_train_left)
tracks[1].train_left.connect(_player_train_left) tracks[1].train_left.connect(_player_train_left)
_unparent_all_stations_except($station_hirschfeld) _unparent_all_stations_except($hirschfeld)
enter_station(current_station) enter_station(current)
var current_station : Node3D = null ## The current station
var current : Station
var stop := false var stop := false
var destinations : Array[Node3D] = [null, null] var destinations : Array[Station] = [null, null]
## Begins the scheduled traffic (looping through the list of destinations) on a given track ## Begins the scheduled traffic (looping through the list of destinations) on a given track
func _begin_traffic_loop(track: Dolly, cancel: Array) -> void: func _begin_traffic_loop(track: Dolly, cancel: Array) -> void:
if fahrplan[current_station][track.index] == null: # empty array (just no routes) would be falsy if not track.player_on_board and fahrplan[current][track.index] == null: # empty trains dont arrive at endstation
_set_signage_texts(track.signage_group, "Gleis gesperrt")
return
if fahrplan[current][track.index] == null: # empty trains dont arrive at endstation
track.arrive(true) track.arrive(true)
_set_signage_texts(track.signage_group, "Endstation") _set_signage_texts(track.signage_group, "Endstation")
return return
var routes : Array = fahrplan[current_station][track.index] var routes : Array = fahrplan[current][track.index]
if routes.is_empty(): if routes.is_empty():
_set_signage_texts(track.signage_group, "Verkehr z. Zt.\nunregelmäßig") _set_signage_texts(track.signage_group, "Verkehr z. Zt.\nunregelmäßig")
return return
@ -57,11 +59,15 @@ func _begin_traffic_loop(track: Dolly, cancel: Array) -> void:
while true: while true:
if cancel.is_empty(): return # abort the loop if cancel.is_empty(): return # abort the loop
var next : Node = routes.pop_front() var line : StringName = routes.pop_front()
var next : Station = routes.pop_front()
routes.append(line) # It's a ring buffer
routes.append(next) # It's a ring buffer routes.append(next) # It's a ring buffer
destinations[track.index] = next destinations[track.index] = next
_set_signage_texts(track.signage_group, next.name) # TODO: load nice string track.set_line(line)
_set_signage_texts(track.signage_group, current.get_label(line, next)) # TODO: load nice string
# Vary our schedule a little by making empty trains wait a random amount of time # Vary our schedule a little by making empty trains wait a random amount of time
if not track.player_on_board: if not track.player_on_board:
@ -73,11 +79,11 @@ func _begin_traffic_loop(track: Dolly, cancel: Array) -> void:
var cancellation_token : Array var cancellation_token : Array
func enter_station(station: Node): func enter_station(station: Station):
prints("------------", "ENTER STATION", station, station.name, "------------") prints("------------", "ENTER STATION", station, station.name, "------------")
remove_child(current_station) remove_child(current)
current_station = station current = station
add_child(current_station) add_child(station)
cancellation_token = ["go"] # Allocate a new stopping token cancellation_token = ["go"] # Allocate a new stopping token
_begin_traffic_loop(tracks[0], cancellation_token) _begin_traffic_loop(tracks[0], cancellation_token)
@ -90,9 +96,9 @@ func _player_train_left(track: Dolly) -> void:
func _unparent_all_stations_except(except : Node3D): func _unparent_all_stations_except(except : Node3D):
for station in stations: for station in stations:
if station == except:
current_station = station
continue
assert(station.get_parent() == self, "A station that isn't a child of Fahrplan is in the Fahrplan: %s" % station.name) assert(station.get_parent() == self, "A station that isn't a child of Fahrplan is in the Fahrplan: %s" % station.name)
remove_child(station)
station.visible = true # Make visible by default, parenting handles visibility and collision station.visible = true # Make visible by default, parenting handles visibility and collision
if station == except:
current = station
continue
remove_child(station)

View File

@ -1,18 +1,8 @@
class_name Station extends Resource extends Node3D
class_name Station
enum id { @export var i18n_key : StringName
HIRSCHFELD, @export var train_labels : Dictionary[StringName,String] = {}
PARITY,
EXUPERY,
ROSENTHAL,
UNI_1,
UNI_2,
MINISTRY
}
@export var station_name: StringName = "" func get_label(line: StringName, next_stop: Station) -> String:
@export var memory: Scenes.id = Scenes.id.YOUTH_DRAVEN return train_labels.get(line+next_stop.name, line+next_stop.name)
@export_file("*.tscn") var station_path: String = ""
@export var arriving_lines: Dictionary[TrainLine.id, float]
@export var departing_lines: Dictionary[TrainLine.id, float]
@export var announcement: AudioStream

View File

@ -1 +1 @@
uid://cyeh7sa20bmcf uid://pmhadgsfinjc

View File

@ -1,9 +1,6 @@
extends Room extends Room
class_name SubwaySequence class_name SubwaySequence
@export var all_stations: Dictionary[Station.id, Station]
@export var all_lines: Dictionary[TrainLine.id, TrainLine]
func _ready() -> void: func _ready() -> void:
id = State.rooms.TRANSITION id = State.rooms.TRANSITION
super._ready() super._ready()
@ -13,11 +10,11 @@ func get_ready_async() -> void:
func start_room_async(): func start_room_async():
await super.start_room_async() await super.start_room_async()
Scenes.player_enable.emit(true) Scenes.player_enable.emit(true)
await Main.curtain.open() await Main.curtain.open()
func pull_save_state(save: SaveGame) -> void: func pull_save_state(save: SaveGame) -> void:
save.sequences_enabled = Scenes.enabled_sequences save.sequences_enabled = Scenes.enabled_sequences

View File

@ -1,6 +1,8 @@
extends Node3D extends Node3D
class_name SubwayTrain class_name SubwayTrain
@export var materials : Dictionary[StringName, Material] = {}
@export var door_open: bool: @export var door_open: bool:
set(open): set(open):
if door_open == open: return if door_open == open: return
@ -11,3 +13,10 @@ class_name SubwayTrain
%TrainModel/AnimationPlayer.play("door_close") %TrainModel/AnimationPlayer.play("door_close")
%FrontWallClosed.disabled = door_open %FrontWallClosed.disabled = door_open
func set_line(line : StringName):
$TrainModel/traun_hull.material_overlay = materials[line]
$TrainModel/LineLabelBack.text = line.to_upper()
$TrainModel/LineLabelFront.text = line.to_upper()

View File

@ -1,14 +0,0 @@
class_name TrainLine extends Resource
enum id {
NONE,
RING,
U2,
U3,
U8
}
@export var train_id: id = id.NONE
@export var destination: StringName = ""
@export var via: StringName = ""
@export var stops: Dictionary[Station, float]

View File

@ -1 +0,0 @@
uid://dfkq0djtygmma

View File

@ -8,6 +8,7 @@
[resource] [resource]
resource_name = "train_windows" resource_name = "train_windows"
transparency = 4 transparency = 4
cull_mode = 2
albedo_texture = ExtResource("1_qqnyp") albedo_texture = ExtResource("1_qqnyp")
metallic = 1.0 metallic = 1.0
metallic_texture = ExtResource("2_orwl3") metallic_texture = ExtResource("2_orwl3")

View File

@ -9,6 +9,7 @@
resource_name = "train_windows_transparent" resource_name = "train_windows_transparent"
transparency = 1 transparency = 1
blend_mode = 4 blend_mode = 4
cull_mode = 2
albedo_texture = ExtResource("1_p8q8d") albedo_texture = ExtResource("1_p8q8d")
metallic = 1.0 metallic = 1.0
metallic_texture = ExtResource("2_eds1u") metallic_texture = ExtResource("2_eds1u")

View File

@ -1,5 +1,5 @@
shader_type spatial; shader_type spatial;
render_mode cull_back, blend_add, unshaded; render_mode cull_disabled, blend_add, unshaded;
varying vec3 world_pos; varying vec3 world_pos;
uniform float state = 0.0; uniform float state = 0.0;

View File

@ -1,4 +1,4 @@
[gd_resource type="ShaderMaterial" format=3 uid="uid://dchm78gv31r6a"] [gd_resource type="ShaderMaterial" load_steps=4 format=3 uid="uid://dchm78gv31r6a"]
[ext_resource type="Shader" uid="uid://dpowid5cwvgu0" path="res://base-environments/transition/shaders/timetravel.gdshader" id="1_0da7x"] [ext_resource type="Shader" uid="uid://dpowid5cwvgu0" path="res://base-environments/transition/shaders/timetravel.gdshader" id="1_0da7x"]
[ext_resource type="Texture2D" uid="uid://dst0u5b51mx4h" path="res://base-environments/transition/shaders/water_color.exr" id="2_4vy32"] [ext_resource type="Texture2D" uid="uid://dst0u5b51mx4h" path="res://base-environments/transition/shaders/water_color.exr" id="2_4vy32"]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
extends Node3D extends Station
func _ready() -> void: func _ready() -> void:
%PlayerDetect.body_entered.connect(func(body): %PlayerDetect.body_entered.connect(func(body):

View File

@ -1,4 +1,4 @@
extends Node3D extends Station
func _ready() -> void: func _ready() -> void:
%PlayerDetect.body_entered.connect(func(body): %PlayerDetect.body_entered.connect(func(body):

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,15 @@
[gd_scene load_steps=25 format=3 uid="uid://df3ur5wll8vx7"] [gd_scene load_steps=31 format=3 uid="uid://df3ur5wll8vx7"]
[ext_resource type="PackedScene" uid="uid://4j1tlhfm3p40" path="res://base-environments/transition/subway_train.tscn" id="1_2h2xx"] [ext_resource type="PackedScene" uid="uid://4j1tlhfm3p40" path="res://base-environments/transition/subway_train.tscn" id="1_2h2xx"]
[ext_resource type="Script" uid="uid://dgfje4druu3sw" path="res://base-environments/transition/code/dolly.gd" id="1_5jpg8"] [ext_resource type="Script" uid="uid://dgfje4druu3sw" path="res://base-environments/transition/code/dolly.gd" id="1_5jpg8"]
[ext_resource type="Script" uid="uid://cyohujvfoiof7" path="res://base-environments/transition/code/subway_train.gd" id="2_aacjs"] [ext_resource type="Script" uid="uid://cyohujvfoiof7" path="res://base-environments/transition/code/subway_train.gd" id="2_aacjs"]
[ext_resource type="AudioStream" uid="uid://cwfr6sgcwg7sl" path="res://base-environments/transition/audio/450918__kyles__metro-subway-montreal-verdun-station-arrive-and-leave-semidistant-from-bridge-over-tracks-overpass.ogg" id="3_4h0n7"] [ext_resource type="AudioStream" uid="uid://cwfr6sgcwg7sl" path="res://base-environments/transition/audio/450918__kyles__metro-subway-montreal-verdun-station-arrive-and-leave-semidistant-from-bridge-over-tracks-overpass.ogg" id="3_4h0n7"]
[ext_resource type="Material" uid="uid://cl7e6lpjalm0c" path="res://base-environments/transition/shaders/u1.material" id="3_j8pin"]
[ext_resource type="Material" uid="uid://c0baqy42xdxtg" path="res://base-environments/transition/shaders/u2.material" id="4_3w708"]
[ext_resource type="Material" uid="uid://bw4y5b5lnw3cn" path="res://base-environments/transition/shaders/u4.material" id="5_3x5rc"]
[ext_resource type="Material" uid="uid://cor0uho8hnfqc" path="res://base-environments/transition/shaders/u7.material" id="6_ckebf"]
[ext_resource type="Material" uid="uid://d0kk76pja0orj" path="res://base-environments/transition/shaders/u8.material" id="7_dyyau"]
[ext_resource type="FontFile" uid="uid://b231f0liphck" path="res://import/fonts/AtkinsonHyperlegible-Regular.ttf" id="10_3w708"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_aacjs"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_aacjs"]
shading_mode = 0 shading_mode = 0
@ -122,6 +128,13 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -150)
[node name="Subway" type="Node3D" parent="."] [node name="Subway" type="Node3D" parent="."]
script = ExtResource("2_aacjs") script = ExtResource("2_aacjs")
materials = Dictionary[StringName, Material]({
&"u1": ExtResource("3_j8pin"),
&"u2": ExtResource("4_3w708"),
&"u4": ExtResource("5_3x5rc"),
&"u7": ExtResource("6_ckebf"),
&"u8": ExtResource("7_dyyau")
})
metadata/_custom_type_script = "uid://cyohujvfoiof7" metadata/_custom_type_script = "uid://cyohujvfoiof7"
[node name="WarpEffecScreen" type="MeshInstance3D" parent="Subway"] [node name="WarpEffecScreen" type="MeshInstance3D" parent="Subway"]
@ -174,7 +187,18 @@ playback_type = 1
[node name="TrainModel" parent="Subway" instance=ExtResource("1_2h2xx")] [node name="TrainModel" parent="Subway" instance=ExtResource("1_2h2xx")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -3.4114173e-08, 0, -0.7804413) transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -3.4114173e-08, 0, -0.7804413)
script = null
[node name="LineLabelFront" type="Label3D" parent="Subway/TrainModel"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, -15.413577, 2.7434583, -6.737489e-07)
text = "U0"
font = ExtResource("10_3w708")
font_size = 64
[node name="LineLabelBack" type="Label3D" parent="Subway/TrainModel"]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 15.410003, 2.7434583, 6.9981036e-07)
text = "U0"
font = ExtResource("10_3w708")
font_size = 64
[node name="Collider" type="AnimatableBody3D" parent="Subway"] [node name="Collider" type="AnimatableBody3D" parent="Subway"]
unique_name_in_owner = true unique_name_in_owner = true

View File

@ -1,20 +1,12 @@
[gd_scene load_steps=15 format=4 uid="uid://4j1tlhfm3p40"] [gd_scene load_steps=14 format=4 uid="uid://4j1tlhfm3p40"]
[ext_resource type="PackedScene" uid="uid://dmh8tmuvftqus" path="res://base-environments/transition/import/subway_train.glb" id="1_8e51f"] [ext_resource type="PackedScene" uid="uid://dmh8tmuvftqus" path="res://base-environments/transition/import/subway_train.glb" id="1_8e51f"]
[ext_resource type="Material" uid="uid://dchm78gv31r6a" path="res://base-environments/transition/shaders/timetravel.tres" id="2_g5p57"] [ext_resource type="Material" uid="uid://dchm78gv31r6a" path="res://base-environments/transition/shaders/timetravel.tres" id="2_g5p57"]
[ext_resource type="Script" uid="uid://cyohujvfoiof7" path="res://base-environments/transition/code/subway_train.gd" id="2_skiem"] [ext_resource type="Material" uid="uid://ddw7mob1qmlbj" path="res://base-environments/transition/shaders/u0.material" id="3_81crm"]
[ext_resource type="Material" uid="uid://rh1lc61j6qd8" path="res://base-environments/transition/import/textures/roof_greeble.tres" id="3_q0ort"] [ext_resource type="Material" uid="uid://rh1lc61j6qd8" path="res://base-environments/transition/import/textures/roof_greeble.tres" id="3_q0ort"]
[ext_resource type="Texture2D" uid="uid://bewykr0twbplg" path="res://base-environments/transition/import/textures/LateralTren_baseColor_upscayl_2x_realesrgan-x4plus-anime.png" id="5_6pwip"] [ext_resource type="Texture2D" uid="uid://bewykr0twbplg" path="res://base-environments/transition/import/textures/LateralTren_baseColor_upscayl_2x_realesrgan-x4plus-anime.png" id="5_6pwip"]
[ext_resource type="VoxelGIData" uid="uid://coibvxeouqllc" path="res://base-environments/transition/vfx/voxelGI_subway_train.tres" id="5_q0ort"] [ext_resource type="VoxelGIData" uid="uid://coibvxeouqllc" path="res://base-environments/transition/vfx/voxelGI_subway_train.tres" id="5_q0ort"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8e51f"]
cull_mode = 2
albedo_color = Color(0.22188288, 0.6046251, 0.8484487, 1)
metallic = 0.5
roughness = 0.5
clearcoat_enabled = true
clearcoat_roughness = 0.2
[sub_resource type="ArrayMesh" id="ArrayMesh_f2ux3"] [sub_resource type="ArrayMesh" id="ArrayMesh_f2ux3"]
_surfaces = [{ _surfaces = [{
"aabb": AABB(-5.128359, -0.2631049, -1.4985942, 10.841061, 0.57964456, 3.1154532), "aabb": AABB(-5.128359, -0.2631049, -1.4985942, 10.841061, 0.57964456, 3.1154532),
@ -52,6 +44,7 @@ shadow_mesh = SubResource("ArrayMesh_f2ux3")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q0ort"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q0ort"]
transparency = 1 transparency = 1
blend_mode = 1 blend_mode = 1
cull_mode = 2
albedo_texture = ExtResource("5_6pwip") albedo_texture = ExtResource("5_6pwip")
roughness = 0.1 roughness = 0.1
@ -144,13 +137,12 @@ _data = {
} }
[node name="subway_train" instance=ExtResource("1_8e51f")] [node name="subway_train" instance=ExtResource("1_8e51f")]
script = ExtResource("2_skiem")
[node name="traun_hull" parent="." index="0"] [node name="traun_hull" parent="." index="0"]
transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, 0) transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, 0)
layers = 4 layers = 4
gi_mode = 2 gi_mode = 2
surface_material_override/0 = SubResource("StandardMaterial3D_8e51f") surface_material_override/0 = ExtResource("3_81crm")
[node name="ApoyaCristalesLateralesPared3_LP_004_LateralesInteriores_0_001" parent="traun_hull" index="0"] [node name="ApoyaCristalesLateralesPared3_LP_004_LateralesInteriores_0_001" parent="traun_hull" index="0"]
layers = 4 layers = 4

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -206,10 +206,6 @@ id = 3
[node name="PlayerController" parent="." instance=ExtResource("2_upyac")] [node name="PlayerController" parent="." instance=ExtResource("2_upyac")]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 2.2023005, 0, 0.7319784) transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 2.2023005, 0, 0.7319784)
initial_pitch = 0.0
[node name="Yaw" parent="PlayerController" index="1"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
[node name="Camera3D" parent="PlayerController/Yaw/Pitch/Mount" index="0"] [node name="Camera3D" parent="PlayerController/Yaw/Pitch/Mount" index="0"]
transform = Transform3D(1, 0, 0, 0, 1.0000006, 0, 0, 0, 1.0000006, 0, 0.202, 0.157) transform = Transform3D(1, 0, 0, 0, 1.0000006, 0, 0, 0, 1.0000006, 0, 0.202, 0.157)

File diff suppressed because one or more lines are too long

View File

@ -632,7 +632,7 @@ mesh = SubResource("CapsuleMesh_x6v75")
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.22534, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.22534, 0)
[node name="Pitch" type="Node3D" parent="Yaw"] [node name="Pitch" type="Node3D" parent="Yaw"]
transform = Transform3D(1, 0, 0, 0, 0.642787, -0.766044, 0, 0.766044, 0.642787, 0, 0, 0) transform = Transform3D(1, 0, 0, 0, 0.9999993, 0, 0, 0, 0.9999993, 0, 0, 0)
[node name="Mount" type="Node3D" parent="Yaw/Pitch"] [node name="Mount" type="Node3D" parent="Yaw/Pitch"]

View File

@ -70,10 +70,10 @@ import/blender/enabled=false
[global_group] [global_group]
interactables="" interactables="Things that can be interacted with to display a Playable"
signage2="" signage2="Track 2 Station Signs"
signage1="" signage1="Track 1 Station Signs"
prompts="All PromptButton inheritors." prompts="All PromptButton inheritors"
[gui] [gui]