From 16251db248407740dd11f468c9794852b3d1873e Mon Sep 17 00:00:00 2001 From: kziolkowski Date: Thu, 10 Jul 2025 19:07:46 +0200 Subject: [PATCH] WIP new SceneTransition system --- scenes/Babushka_scene_bootstrap.tscn | 89 +++++++++++++- scenes/Babushka_scene_farm_outside_2d.tscn | 16 +-- scenes/Babushka_scene_indoor_common_room.tscn | 11 ++ scenes/Babushka_scene_indoor_vesnas_room.tscn | 114 +++++++++--------- .../SceneTransitionThreaded.cs | 88 ++++++++++++++ .../SceneTransitionThreaded.cs.uid | 1 + scripts/CSharp/Common/SceneTransition.cs | 21 ++++ 7 files changed, 271 insertions(+), 69 deletions(-) create mode 100644 scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs create mode 100644 scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs.uid diff --git a/scenes/Babushka_scene_bootstrap.tscn b/scenes/Babushka_scene_bootstrap.tscn index 252f873..3d422c5 100644 --- a/scenes/Babushka_scene_bootstrap.tscn +++ b/scenes/Babushka_scene_bootstrap.tscn @@ -1,10 +1,95 @@ -[gd_scene load_steps=2 format=3 uid="uid://bopv10dqm1knc"] +[gd_scene load_steps=7 format=3 uid="uid://bopv10dqm1knc"] [ext_resource type="PackedScene" uid="uid://c6wnoif01ltld" path="res://scenes/Babushka_scene_startMenu.tscn" id="1_15ton"] +[ext_resource type="Script" uid="uid://bo2jik2jtuqlw" path="res://scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs" id="1_d3jfo"] -[node name="BabushkaSceneBootstrap" type="Node2D"] +[sub_resource type="Animation" id="Animation_t7str"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("SceneFadeAnimation/CanvasLayer/ColorRect:color") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 0)] +} + +[sub_resource type="Animation" id="Animation_e43hv"] +resource_name = "fadeIn" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("SceneFadeAnimation/CanvasLayer/ColorRect:color") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.966667), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(0, 0, 0, 0), Color(0, 0, 0, 1)] +} +tracks/1/type = "method" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0.966667), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"OnFadeInCompletedThreaded" +}] +} + +[sub_resource type="Animation" id="Animation_d3jfo"] +resource_name = "fadeOut" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("SceneFadeAnimation/CanvasLayer/ColorRect:color") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.966667), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(0, 0, 0, 1), Color(0, 0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_5o782"] +_data = { +&"RESET": SubResource("Animation_t7str"), +&"fadeIn": SubResource("Animation_e43hv"), +&"fadeOut": SubResource("Animation_d3jfo") +} + +[node name="BabushkaSceneBootstrap" type="Node2D" node_paths=PackedStringArray("animationPlayer")] +script = ExtResource("1_d3jfo") +animationPlayer = NodePath("SceneFadeAnimation") [node name="BabushkaSceneStartMenu" parent="." node_paths=PackedStringArray("_sceneInstanceParent") instance=ExtResource("1_15ton")] _sceneInstanceParent = NodePath("../SceneParent") [node name="SceneParent" type="Node" parent="."] + +[node name="SceneFadeAnimation" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_5o782") +} + +[node name="CanvasLayer" type="CanvasLayer" parent="SceneFadeAnimation"] + +[node name="ColorRect" type="ColorRect" parent="SceneFadeAnimation/CanvasLayer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(1, 1, 1, 0) diff --git a/scenes/Babushka_scene_farm_outside_2d.tscn b/scenes/Babushka_scene_farm_outside_2d.tscn index 5db2a77..ec26c25 100644 --- a/scenes/Babushka_scene_farm_outside_2d.tscn +++ b/scenes/Babushka_scene_farm_outside_2d.tscn @@ -1,8 +1,7 @@ -[gd_scene load_steps=99 format=3 uid="uid://gigb28qk8t12"] +[gd_scene load_steps=98 format=3 uid="uid://gigb28qk8t12"] [ext_resource type="PackedScene" uid="uid://c25udixd5m6l0" path="res://prefabs/characters/Player2D.tscn" id="1_7wfwe"] [ext_resource type="Texture2D" uid="uid://8sr11ex30n0m" path="res://art/mockups/Kenney_Backgrounds/Samples/uncolored_hills.png" id="2_7b2ri"] -[ext_resource type="PackedScene" uid="uid://bm21nqepnwaik" path="res://scenes/Babushka_scene_indoor_common_room.tscn" id="2_taxvr"] [ext_resource type="Script" uid="uid://bqomwxclsbhd3" path="res://scripts/CSharp/Common/Camera/CameraController.cs" id="3_p4qqi"] [ext_resource type="Texture2D" uid="uid://be1nofeo7an0" path="res://art/mockups/Kenney_Backgrounds/PNG/cloud2.png" id="3_r34wi"] [ext_resource type="Texture2D" uid="uid://o6vnf7n7qp8o" path="res://art/mockups/Kenney_Backgrounds/PNG/cloud6.png" id="4_xh22q"] @@ -245,7 +244,7 @@ stream_2/stream = ExtResource("49_d77e7") [node name="BabushkaSceneFarmOutside2d" type="Node2D"] script = ExtResource("34_e5b7x") -_sceneToLoad = ExtResource("2_taxvr") +_sceneNamesToLoad = PackedStringArray("res://scenes/Babushka_scene_indoor_common_room.tscn") [node name="Camera2D" type="Camera2D" parent="." node_paths=PackedStringArray("_followNode")] position = Vector2(3180, 1961) @@ -1115,6 +1114,7 @@ polygon = PackedVector2Array(247.227, 43.5123, 44.7822, 43.5123, -87.2178, 45.12 [node name="EnterHouseInteraction" parent="YSorted/Farm visuals/Static" instance=ExtResource("27_klb81")] position = Vector2(5839, 2349) scale = Vector2(2.425, 2.425) +_id = 0 [node name="greenery" type="Node2D" parent="YSorted/Farm visuals/Static"] @@ -2173,14 +2173,6 @@ position = Vector2(-5016, 3361) [node name="CanvasLayer" parent="." instance=ExtResource("32_2nee2")] [node name="Inventory" parent="CanvasLayer" index="1"] -anchors_preset = 7 -anchor_top = 1.0 -anchor_bottom = 1.0 -offset_left = -116.0 -offset_top = -53.0 -offset_right = 231.82 -offset_bottom = 141.4 -grow_vertical = 0 size_flags_horizontal = 6 size_flags_vertical = 10 @@ -2248,7 +2240,7 @@ script = ExtResource("40_w3jkj") [connection signal="InteractedTool" from="YSorted/BrĂ¼nnen/InteractionArea" to="YSorted/Vesna" method="TryFillWateringCan"] [connection signal="SuccessfulPickUp" from="YSorted/CanGenericPickup" to="YSorted/Vesna" method="HandlePickUp"] [connection signal="SuccessfulPickUp" from="YSorted/RakeGenericPickup" to="YSorted/Vesna" method="HandlePickUp"] -[connection signal="Interacted" from="YSorted/Farm visuals/Static/EnterHouseInteraction" to="." method="LoadScene"] +[connection signal="InteractedTool" from="YSorted/Farm visuals/Static/EnterHouseInteraction" to="." method="LoadSceneAtIndex"] [connection signal="FieldCreated" from="YSorted/Farm visuals/FieldParent" to="Audio/SFX/Farming SFX" method="PlayOneShot"] [connection signal="input_event" from="YSorted/Farm visuals/FieldParent/Area2D" to="YSorted/Vesna/FarmingControls" method="InputEventPressedOn"] [connection signal="finished" from="Audio/Background Music Ramp up" to="Audio/Background Music loop" method="PlayFromOffset"] diff --git a/scenes/Babushka_scene_indoor_common_room.tscn b/scenes/Babushka_scene_indoor_common_room.tscn index d8a570f..afc7321 100644 --- a/scenes/Babushka_scene_indoor_common_room.tscn +++ b/scenes/Babushka_scene_indoor_common_room.tscn @@ -197,6 +197,7 @@ radius = 300.0 [node name="IndoorTest" type="Node2D"] y_sort_enabled = true script = ExtResource("1_3vr4f") +_sceneNamesToLoad = PackedStringArray("res://scenes/Babushka_scene_indoor_vesnas_room.tscn", "res://scenes/Babushka_scene_farm_outside_2d.tscn") [node name="Foreground" type="Node" parent="."] @@ -532,9 +533,19 @@ _followNode = NodePath("../Vesna/CharacterBody2D") [node name="CanvasLayer" parent="." instance=ExtResource("24_yd2gv")] +[node name="VesnasRoomDoor" parent="." instance=ExtResource("11_gpagp")] +position = Vector2(-4855, 32) +_id = 0 + +[node name="OutsideDoor" parent="." instance=ExtResource("11_gpagp")] +position = Vector2(929, 32) +_id = 1 + [connection signal="Interacted" from="BackWall/Room01PechkaDoor/InteractionArea" to="BackWall/Room01PechkaDoor/InteractionArea" method="ToggleActive"] [connection signal="Interacted" from="BackWall/Room01PechkaDoor/InteractionArea" to="BackWall/Room assets/hand" method="PlayAnimation"] [connection signal="timelineEnded" from="Yeli/dialogic_toggle" to="Yeli/Beetroot Quest trigger" method="Trigger"] +[connection signal="InteractedTool" from="VesnasRoomDoor" to="." method="LoadSceneAtIndex"] +[connection signal="InteractedTool" from="OutsideDoor" to="." method="LoadSceneAtIndex"] [editable path="BackWall/Room01PechkaDoor/InteractionArea"] [editable path="Vesna"] diff --git a/scenes/Babushka_scene_indoor_vesnas_room.tscn b/scenes/Babushka_scene_indoor_vesnas_room.tscn index c3e42c1..5c58f67 100644 --- a/scenes/Babushka_scene_indoor_vesnas_room.tscn +++ b/scenes/Babushka_scene_indoor_vesnas_room.tscn @@ -1,25 +1,62 @@ -[gd_scene load_steps=12 format=3 uid="uid://ceaa2qj2bmw43"] +[gd_scene load_steps=11 format=3 uid="uid://ceaa2qj2bmw43"] [ext_resource type="Script" uid="uid://cssdu8viimwm6" path="res://scripts/CSharp/Common/SceneTransition.cs" id="1_c6eln"] [ext_resource type="Texture2D" uid="uid://cugtxcfuds31r" path="res://art/indoor/Babushka_bg_01.png" id="2_j25a2"] +[ext_resource type="PackedScene" uid="uid://bm21nqepnwaik" path="res://scenes/Babushka_scene_indoor_common_room.tscn" id="2_oejul"] +[ext_resource type="PackedScene" uid="uid://cqc72e4hq6bcd" path="res://prefabs/interactions/interaction_area_2d.tscn" id="8_phqdf"] [ext_resource type="Texture2D" uid="uid://cop1vjvhwlsec" path="res://art/indoor/room export/Room_01_shelf.png" id="13_11fdt"] [ext_resource type="PackedScene" uid="uid://c25udixd5m6l0" path="res://prefabs/characters/Player2D.tscn" id="18_3gevq"] -[ext_resource type="PackedScene" uid="uid://dfvgp1my5rydh" path="res://prefabs/characters/Yeli.tscn" id="19_pn0wu"] -[ext_resource type="Script" uid="uid://cvkw4qd2hxksi" path="res://scripts/GdScript/dialogic_toggle.gd" id="20_1j6kg"] -[ext_resource type="Script" uid="uid://cldtt4atgymm5" path="res://scripts/CSharp/Common/Quest/QuestTrigger.cs" id="21_ysphm"] -[ext_resource type="Resource" uid="uid://cbpurnewhyefa" path="res://resources/quests/beetRoot.tres" id="22_5tnro"] [ext_resource type="Script" uid="uid://bqomwxclsbhd3" path="res://scripts/CSharp/Common/Camera/CameraController.cs" id="23_408bg"] [ext_resource type="PackedScene" uid="uid://cgjc4wurbgimy" path="res://prefabs/UI/Inventory/Inventory.tscn" id="24_xwo8y"] -[sub_resource type="CircleShape2D" id="CircleShape2D_wuntg"] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_l0jrn"] resource_local_to_scene = true -radius = 300.0 +size = Vector2(3836, 1086) -[node name="IndoorTest" type="Node2D"] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_2spkc"] +size = Vector2(238.25, 189.75) + +[node name="VesnasRoom" type="Node2D"] y_sort_enabled = true script = ExtResource("1_c6eln") +_sceneToLoad = ExtResource("2_oejul") + +[node name="Colliders" type="Node2D" parent="."] +position = Vector2(1297, 5292) +scale = Vector2(4, 4) + +[node name="SideColliderLeft" type="StaticBody2D" parent="Colliders"] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Colliders/SideColliderLeft"] +position = Vector2(-2892, -1168) +shape = SubResource("RectangleShape2D_l0jrn") + +[node name="SideColliderRight" type="StaticBody2D" parent="Colliders"] +position = Vector2(4858, 0) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Colliders/SideColliderRight"] +position = Vector2(-2892, -1168) +shape = SubResource("RectangleShape2D_l0jrn") + +[node name="TopCollider" type="StaticBody2D" parent="Colliders"] +position = Vector2(2440.5, -1061) -[node name="Foreground" type="Node" parent="."] +[node name="CollisionShape2D" type="CollisionShape2D" parent="Colliders/TopCollider"] +position = Vector2(-2892, -1168) +shape = SubResource("RectangleShape2D_l0jrn") + +[node name="BottomCollider" type="StaticBody2D" parent="Colliders"] +position = Vector2(2495.5, 757.75) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Colliders/BottomCollider"] +position = Vector2(-2892, -1168) +shape = SubResource("RectangleShape2D_l0jrn") + +[node name="BedCollider" type="StaticBody2D" parent="Colliders"] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Colliders/BedCollider"] +position = Vector2(-828.625, -1230.38) +shape = SubResource("RectangleShape2D_2spkc") [node name="BackWall" type="Node" parent="."] @@ -30,69 +67,36 @@ scale = Vector2(2, 2) texture = ExtResource("2_j25a2") offset = Vector2(-2768, 264) -[node name="Room01Walls3" type="Sprite2D" parent="BackWall"] -z_index = -100 -position = Vector2(900, -481) -scale = Vector2(2, 2) -texture = ExtResource("2_j25a2") -offset = Vector2(-2768, 264) - [node name="Room01Shelf" type="Sprite2D" parent="BackWall"] z_index = -50 -position = Vector2(-880, -416) +position = Vector2(-1978, -678) texture = ExtResource("13_11fdt") region_enabled = true region_rect = Rect2(1846, 471, 348, 490) [node name="Vesna" parent="." instance=ExtResource("18_3gevq")] -position = Vector2(-1464, 136) - -[node name="Yeli" parent="." instance=ExtResource("19_pn0wu")] -position = Vector2(-2912, 432) -_timelinesToPlay = PackedStringArray("quest3_beets_start") - -[node name="CollisionShape3D" parent="Yeli/InteractionArea/Area2D" index="0"] -position = Vector2(-205.348, 131.907) -shape = SubResource("CircleShape2D_wuntg") - -[node name="Label" parent="Yeli/InteractionArea" index="1"] -offset_left = -332.62 -offset_top = -99.8217 -offset_right = -85.6204 -offset_bottom = 3.17825 - -[node name="AnimatedSprite" parent="Yeli/TalkingControl" index="0"] -position = Vector2(-576, 368) - -[node name="CollisionShape2D" parent="Yeli/AnimatableBody2D" index="0"] -position = Vector2(-565, 464) - -[node name="dialogic_toggle" type="Node2D" parent="Yeli"] -script = ExtResource("20_1j6kg") -metadata/_custom_type_script = "uid://cvkw4qd2hxksi" - -[node name="Beetroot Quest trigger" type="Node2D" parent="Yeli"] -script = ExtResource("21_ysphm") -questResource = ExtResource("22_5tnro") -toStatus = 1 -makeCurrent = true +position = Vector2(-471, 185) [node name="Camera2D" type="Camera2D" parent="." node_paths=PackedStringArray("_followNode")] position = Vector2(-1534, -26) offset = Vector2(0, -200) zoom = Vector2(0.5, 0.5) -limit_left = -6300 -limit_top = -1050 -limit_right = 1400 -limit_bottom = 1150 +limit_left = -2600 +limit_top = -1400 +limit_right = 1500 +limit_bottom = 1400 editor_draw_limits = true script = ExtResource("23_408bg") _followNode = NodePath("../Vesna/CharacterBody2D") [node name="CanvasLayer" parent="." instance=ExtResource("24_xwo8y")] -[connection signal="timelineEnded" from="Yeli/dialogic_toggle" to="Yeli/Beetroot Quest trigger" method="Trigger"] +[node name="BedInteraction" parent="." instance=ExtResource("8_phqdf")] +position = Vector2(-1560, 158) + +[node name="DoorInteraction" parent="." instance=ExtResource("8_phqdf")] +position = Vector2(777, 201) + +[connection signal="Interacted" from="DoorInteraction" to="." method="LoadScene"] [editable path="Vesna"] -[editable path="Yeli"] -[editable path="Yeli/InteractionArea"] diff --git a/scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs b/scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs new file mode 100644 index 0000000..6621a83 --- /dev/null +++ b/scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs @@ -0,0 +1,88 @@ +using Godot; + +namespace Babushka.scripts.CSharp.Common.SceneManagement; +public partial class SceneTransitionThreaded : Node2D +{ + public static SceneTransitionThreaded Instance { get; private set; } + + // set to true if don't wanna use it + public bool userCodeLoadCompleted = true; + + private ThreadedLoadingStateEn threadedLoadingState = ThreadedLoadingStateEn._none; + public enum ThreadedLoadingStateEn + { + _none, + _fading_in, + _loading, + _loading_user_code + } + + [Export] private AnimationPlayer animationPlayer; + private string scenePathThreaded = ""; + + public override void _EnterTree() + { + Instance = this; + } + + public override void _Process(double delta) + { + CheckLoadThreaded(); + } + + private void CheckLoadThreaded() + { + if (scenePathThreaded == "") + { return; } + + if (threadedLoadingState == ThreadedLoadingStateEn._loading && ResourceLoader.LoadThreadedGetStatus(scenePathThreaded) == ResourceLoader.ThreadLoadStatus.Loaded) + { + OnResourceLoadThreadedComplete(); + } + else if (threadedLoadingState == ThreadedLoadingStateEn._loading_user_code && userCodeLoadCompleted) + { + OnResourceLoadThreadedCompleteUserCode(); + } + } + + public async void ChangeSceneToFile(string scenePath) + { + animationPlayer.Play("fadeIn"); + //yield(animationPlayer, "animation_finished"); + await ToSignal(animationPlayer, "animation_finished"); + GetTree().ChangeSceneToFile(scenePath); + animationPlayer.Play("fadeOut"); + } + + public void OnFadeInCompletedThreaded() + { + if (scenePathThreaded == "") + { return; } + + ResourceLoader.LoadThreadedRequest(scenePathThreaded); + threadedLoadingState = ThreadedLoadingStateEn._loading; + } + + // https://docs.godotengine.org/en/stable/tutorials/io/background_loading.html + public void ChangeSceneToFileThreaded(string scenePath) + { + scenePathThreaded = scenePath; + animationPlayer.Play("fadeIn"); + threadedLoadingState = ThreadedLoadingStateEn._fading_in; + } + + private void OnResourceLoadThreadedComplete() + { + PackedScene loadedScene = (PackedScene)ResourceLoader.LoadThreadedGet(scenePathThreaded); + //Node sceneInstance = loadedScene.Instantiate(); + GetTree().ChangeSceneToPacked(loadedScene); + threadedLoadingState = ThreadedLoadingStateEn._loading_user_code; + } + + private void OnResourceLoadThreadedCompleteUserCode() + { + animationPlayer.Play("fadeOut"); + scenePathThreaded = ""; + threadedLoadingState = ThreadedLoadingStateEn._none; + } +} \ No newline at end of file diff --git a/scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs.uid b/scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs.uid new file mode 100644 index 0000000..9f3a17b --- /dev/null +++ b/scripts/CSharp/Common/SceneManagement/SceneTransitionThreaded.cs.uid @@ -0,0 +1 @@ +uid://bo2jik2jtuqlw diff --git a/scripts/CSharp/Common/SceneTransition.cs b/scripts/CSharp/Common/SceneTransition.cs index ce16126..479e8a4 100644 --- a/scripts/CSharp/Common/SceneTransition.cs +++ b/scripts/CSharp/Common/SceneTransition.cs @@ -1,3 +1,5 @@ +using System.Threading.Tasks; +using Babushka.scripts.CSharp.Common.SceneManagement; using Godot; namespace Babushka.scripts.CSharp.Common; @@ -5,9 +7,12 @@ namespace Babushka.scripts.CSharp.Common; public partial class SceneTransition : Node { [Export] private PackedScene _sceneToLoad; + [Export] private string[] _sceneNamesToLoad; + [Export] private int _sceneIndex; [Export] private Node? _sceneInstanceParent; [Export] private bool _unloadSelf = true; + // todo: remove and replace with indexed system public void LoadScene() { Node sceneInstance = _sceneToLoad.Instantiate(); @@ -24,6 +29,22 @@ public partial class SceneTransition : Node } } + public void LoadSceneAtIndex(int index) + { + string sceneName = _sceneNamesToLoad[index]; + SceneTransitionThreaded.Instance.ChangeSceneToFileThreaded(sceneName); + UnloadAfterDelay(); + } + + private async void UnloadAfterDelay() + { + await ToSignal(GetTree().CreateTimer(1.0f), "timeout"); // 1.0f seconds + if (_unloadSelf) + { + QueueFree(); + } + } + public void Quit() { GetTree().Quit();