Add scene switcher for controlled scene switches

This commit is contained in:
Jens Pitkänen 2024-08-20 17:49:38 +03:00
parent 207629e014
commit e5215356f3
4 changed files with 133 additions and 3 deletions

View File

@ -11,7 +11,7 @@ config_version=5
[application] [application]
config/name="gmtk24" config/name="gmtk24"
run/main_scene="res://scenes/demo/demo.tscn" run/main_scene="res://scenes/entrypoint_scene.tscn"
config/features=PackedStringArray("4.3", "C#", "Forward Plus") config/features=PackedStringArray("4.3", "C#", "Forward Plus")
config/icon="res://misc/icon.svg" config/icon="res://misc/icon.svg"

View File

@ -0,0 +1,27 @@
[gd_scene load_steps=4 format=3 uid="uid://c5ksyousvxx7x"]
[ext_resource type="PackedScene" uid="uid://dv81sy34l8ice" path="res://scenes/stairs/stairs.tscn" id="1_00r22"]
[ext_resource type="Script" path="res://scripts/SceneSwitcher.cs" id="1_ps0jf"]
[ext_resource type="PackedScene" uid="uid://8po7ftboqq4k" path="res://scenes/demo/demo.tscn" id="2_rf0rf"]
[node name="EntrypointScene" type="Node" node_paths=PackedStringArray("LoadingScreen")]
process_mode = 3
script = ExtResource("1_ps0jf")
AddedLoadingScreenSeconds = 0.3
LoadingScreen = NodePath("LoadingScreen")
DemoScene = ExtResource("2_rf0rf")
StairsScene = ExtResource("1_00r22")
[node name="LoadingScreen" type="CenterContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 4.0
offset_right = 4.0
grow_horizontal = 2
grow_vertical = 2
[node name="Label" type="Label" parent="LoadingScreen"]
layout_mode = 2
theme_override_font_sizes/font_size = 36
text = "Loading..."

View File

@ -73,10 +73,9 @@ text = "Continue"
custom_minimum_size = Vector2(340, 200) custom_minimum_size = Vector2(340, 200)
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
current_tab = 3 current_tab = 0
[node name="General settings" type="MarginContainer" parent="CenterContainer/HBoxContainer/OptionsAndButtonsContainer/MarginContainer/Options and buttons/TabContainer"] [node name="General settings" type="MarginContainer" parent="CenterContainer/HBoxContainer/OptionsAndButtonsContainer/MarginContainer/Options and buttons/TabContainer"]
visible = false
layout_mode = 2 layout_mode = 2
theme_override_constants/margin_left = 10 theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10 theme_override_constants/margin_top = 10
@ -213,6 +212,7 @@ size_flags_horizontal = 3
action_mode = 0 action_mode = 0
[node name="Graphics" type="MarginContainer" parent="CenterContainer/HBoxContainer/OptionsAndButtonsContainer/MarginContainer/Options and buttons/TabContainer"] [node name="Graphics" type="MarginContainer" parent="CenterContainer/HBoxContainer/OptionsAndButtonsContainer/MarginContainer/Options and buttons/TabContainer"]
visible = false
layout_mode = 2 layout_mode = 2
theme_override_constants/margin_left = 10 theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10 theme_override_constants/margin_top = 10

103
scripts/SceneSwitcher.cs Normal file
View File

@ -0,0 +1,103 @@
using System.Threading;
using Godot;
namespace Gmtk24 {
public partial class SceneSwitcher : Node {
public enum Scene {
Demo,
Stairs,
}
/// <summary>This is the entrypoint of the godot project, and never gets
/// unloaded. Set when the entrypoint scene is loaded.</summary>
public static SceneSwitcher Singleton { get; private set; }
[Export]
public float AddedLoadingScreenSeconds = 0.5f;
[Export]
public Control LoadingScreen;
[Export]
public PackedScene DemoScene;
[Export]
public PackedScene StairsScene;
private PackedScene NextScene = null;
private Node InstantiatedScene = null;
private bool SceneLoaded = false;
/// <summary>The instantiation is deferred a bit to let the loading
/// screen actually render in case the loading takes more than a few
/// milliseconds.</summary>
private float SceneLoadCooldown = 0;
public override void _Ready() {
Singleton = this;
SwitchToScene(Scene.Demo);
}
public override void _UnhandledInput(InputEvent @event) {
if (@event is InputEventKey keyEv && keyEv.Pressed && keyEv.CtrlPressed) {
if (keyEv.Keycode == Key.F1) {
SwitchToScene(Scene.Demo);
GetViewport().SetInputAsHandled();
}
if (keyEv.Keycode == Key.F2) {
SwitchToScene(Scene.Stairs);
GetViewport().SetInputAsHandled();
}
}
}
public override void _Process(double delta) {
if (!SceneLoaded) {
SceneLoadCooldown -= (float)delta;
if (SceneLoadCooldown <= 0 && NextScene != null) {
LoadNextScene();
NextScene = null;
SceneLoaded = true;
LoadingScreen.Visible = false;
}
}
}
public void SwitchToScene(Scene newScene) {
PackedScene sceneToInstantiate = null;
switch (newScene) {
case Scene.Demo:
sceneToInstantiate = DemoScene;
break;
case Scene.Stairs:
sceneToInstantiate = StairsScene;
break;
}
if (sceneToInstantiate == null) {
GD.PrintErr("Tried to switch scenes to Scene." + newScene + " but it hasn't been set up in the entrypoint scene!");
return;
}
NextScene = sceneToInstantiate;
if (IsInstanceValid(InstantiatedScene)) {
RemoveChild(InstantiatedScene);
InstantiatedScene.QueueFree();
}
LoadingScreen.Visible = true;
SceneLoadCooldown = AddedLoadingScreenSeconds;
SceneLoaded = false;
}
private void LoadNextScene() {
if (NextScene == null) {
return;
}
InstantiatedScene = NextScene.Instantiate();
if (InstantiatedScene.ProcessMode == ProcessModeEnum.Inherit) {
InstantiatedScene.ProcessMode = ProcessModeEnum.Pausable;
}
AddChild(InstantiatedScene);
MoveChild(InstantiatedScene, 0);
}
}
}