├── marketing ├── cover.png └── cover.png.import ├── assets ├── Raleway-Regular.ttf ├── Door-Bell-Ding-A1-www.fesliyanstudios.com.wav ├── Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav ├── raleway24.tres ├── raleway32.tres ├── raleway48.tres ├── Door-Bell-Ding-A1-www.fesliyanstudios.com.wav.import └── Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav.import ├── .gitignore ├── default_env.tres ├── Main.tscn ├── project.godot ├── Level.gd ├── SceneSwitcher.gd ├── README.md ├── SceneSwitcher.tscn ├── DesertLevel.tscn └── GrassLevel.tscn /marketing/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephmbustamante/Godot-Level-Switcher-Tutorial/HEAD/marketing/cover.png -------------------------------------------------------------------------------- /assets/Raleway-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephmbustamante/Godot-Level-Switcher-Tutorial/HEAD/assets/Raleway-Regular.ttf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Godot-specific ignores 3 | .import/ 4 | export.cfg 5 | export_presets.cfg 6 | 7 | # Mono-specific ignores 8 | .mono/ 9 | 10 | Export/ 11 | -------------------------------------------------------------------------------- /assets/Door-Bell-Ding-A1-www.fesliyanstudios.com.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephmbustamante/Godot-Level-Switcher-Tutorial/HEAD/assets/Door-Bell-Ding-A1-www.fesliyanstudios.com.wav -------------------------------------------------------------------------------- /default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | 5 | [resource] 6 | background_mode = 2 7 | background_sky = SubResource( 1 ) 8 | -------------------------------------------------------------------------------- /assets/Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephmbustamante/Godot-Level-Switcher-Tutorial/HEAD/assets/Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav -------------------------------------------------------------------------------- /Main.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=2] 2 | 3 | [ext_resource path="res://SceneSwitcher.tscn" type="PackedScene" id=1] 4 | 5 | [node name="Main" type="Node2D"] 6 | 7 | [node name="SceneSwitcher" parent="." instance=ExtResource( 1 )] 8 | -------------------------------------------------------------------------------- /assets/raleway24.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://assets/Raleway-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 24 7 | font_data = ExtResource( 1 ) 8 | -------------------------------------------------------------------------------- /assets/raleway32.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://assets/Raleway-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 32 7 | font_data = ExtResource( 1 ) 8 | -------------------------------------------------------------------------------- /assets/raleway48.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="DynamicFont" load_steps=2 format=2] 2 | 3 | [ext_resource path="res://assets/Raleway-Regular.ttf" type="DynamicFontData" id=1] 4 | 5 | [resource] 6 | size = 48 7 | font_data = ExtResource( 1 ) 8 | -------------------------------------------------------------------------------- /project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=4 10 | 11 | [application] 12 | 13 | config/name="Godot Level Switcher Tutorial" 14 | run/main_scene="res://Main.tscn" 15 | 16 | [physics] 17 | 18 | common/enable_pause_aware_picking=true 19 | 20 | [rendering] 21 | 22 | environment/default_environment="res://default_env.tres" 23 | -------------------------------------------------------------------------------- /assets/Door-Bell-Ding-A1-www.fesliyanstudios.com.wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamSample" 5 | path="res://.import/Door-Bell-Ding-A1-www.fesliyanstudios.com.wav-11a99ca76f14dd821e801dc24d52e12a.sample" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/Door-Bell-Ding-A1-www.fesliyanstudios.com.wav" 10 | dest_files=[ "res://.import/Door-Bell-Ding-A1-www.fesliyanstudios.com.wav-11a99ca76f14dd821e801dc24d52e12a.sample" ] 11 | 12 | [params] 13 | 14 | force/8_bit=false 15 | force/mono=false 16 | force/max_rate=false 17 | force/max_rate_hz=44100 18 | edit/trim=false 19 | edit/normalize=false 20 | edit/loop=false 21 | compress/mode=0 22 | -------------------------------------------------------------------------------- /assets/Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="wav" 4 | type="AudioStreamSample" 5 | path="res://.import/Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav-db71cc94b36ea3a62bf31fe967b1e578.sample" 6 | 7 | [deps] 8 | 9 | source_file="res://assets/Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav" 10 | dest_files=[ "res://.import/Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav-db71cc94b36ea3a62bf31fe967b1e578.sample" ] 11 | 12 | [params] 13 | 14 | force/8_bit=false 15 | force/mono=false 16 | force/max_rate=false 17 | force/max_rate_hz=44100 18 | edit/trim=false 19 | edit/normalize=false 20 | edit/loop=false 21 | compress/mode=0 22 | -------------------------------------------------------------------------------- /marketing/cover.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/cover.png-d3223a21453b6b4614c102d9cbe585f2.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://marketing/cover.png" 13 | dest_files=[ "res://.import/cover.png-d3223a21453b6b4614c102d9cbe585f2.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | process/normal_map_invert_y=false 32 | stream=false 33 | size_limit=0 34 | detect_3d=true 35 | svg/scale=1.0 36 | -------------------------------------------------------------------------------- /Level.gd: -------------------------------------------------------------------------------- 1 | extends CanvasLayer 2 | 3 | 4 | signal level_changed(level_name) 5 | 6 | export (String) var level_name = "level" 7 | 8 | var level_parameters := { 9 | "clicks": 0 10 | } 11 | 12 | 13 | func load_level_parameters(new_level_parameters: Dictionary): 14 | level_parameters = new_level_parameters 15 | $ClickLabel.text = "Clicks: " + str(level_parameters.clicks) 16 | 17 | 18 | func play_loaded_sound() -> void: 19 | $LevelLoadedSound.play() 20 | $ChangeSceneButton.disabled = false 21 | 22 | 23 | func cleanup(): 24 | if $ButtonClickedSound.playing: 25 | yield($ButtonClickedSound, "finished") 26 | queue_free() 27 | 28 | 29 | func set_clicks(new_click_amount: int): 30 | level_parameters.clicks = new_click_amount 31 | $ClickLabel.text = "Clicks: " + str(level_parameters.clicks) 32 | 33 | 34 | func _on_ChangeSceneButton_pressed() -> void: 35 | $ButtonClickedSound.play() 36 | $ChangeSceneButton.disabled = true 37 | emit_signal("level_changed", level_name) 38 | 39 | 40 | func _on_ClickButton_pressed() -> void: 41 | set_clicks(level_parameters.clicks + 1) 42 | -------------------------------------------------------------------------------- /SceneSwitcher.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | 4 | var next_level = null 5 | 6 | onready var current_level = $GrassLevel 7 | onready var anim = $AnimationPlayer 8 | 9 | 10 | func _ready() -> void: 11 | current_level.connect("level_changed", self, "handle_level_changed") 12 | current_level.play_loaded_sound() 13 | 14 | 15 | func handle_level_changed(current_level_name: String): 16 | var next_level_name: String 17 | 18 | match current_level_name: 19 | "grass": 20 | next_level_name = "Desert" 21 | "desert": 22 | next_level_name = "Grass" 23 | _: 24 | return 25 | 26 | next_level = load("res://" + next_level_name + "Level.tscn").instance() 27 | next_level.layer = -1 28 | add_child(next_level) 29 | anim.play("fade_in") 30 | next_level.connect("level_changed", self, "handle_level_changed") 31 | transfer_data_between_scenes(current_level, next_level) 32 | 33 | 34 | func transfer_data_between_scenes(old_scene, new_scene): 35 | new_scene.load_level_parameters(old_scene.level_parameters) 36 | 37 | 38 | func _on_AnimationPlayer_animation_finished(anim_name: String) -> void: 39 | match anim_name: 40 | "fade_in": 41 | current_level.cleanup() 42 | current_level = next_level 43 | current_level.layer = 1 44 | next_level = null 45 | anim.play("fade_out") 46 | "fade_out": 47 | current_level.play_loaded_sound() 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot Scene Changer Tutorial 2 | This repository contains the source code for the Godot Scene Changer Tutorial series. 3 | 4 | [You can follow along with the series on YouTube.](https://www.youtube.com/watch?v=XHbrKdsZrxY&list=PLpwc3ughKbZe2jkEs0w-PdPg-PZJ0457x) 5 | 6 | ## How to Use This Repository 7 | 8 | Unfortunately, I don't have separate commits for this series, so the code here represents the final form of the project after episode 3. Sorry for any inconvenience! 9 | 10 | If there is a bug or issue with the code, feel free to open an issue here or reach out on the Discord server (Discord is preferable since I check it more, but I'll eventually see it here). 11 | 12 | ## Join our Community Discord 13 | 14 | If you have questions about the tutorial or the code, or just want to connect with other developers, join our community Discord by following the link below. 15 | I or another member will be happy to help and we have an active community of developers there. We'd love to have you! 16 | 17 | [Click here to join our Discord.](https://discord.gg/e4BxZbe) 18 | 19 | ## Support my Work 20 | 21 | If you've found this tutorial series helpful, please consider supporting my work by [buying me a coffee.](https://www.buymeacoffee.com/jmbiv) 22 | 23 | Thanks so much for watching, and I hope you find these tutorials helpful! If you use them to make your own game, or just find some of the concepts I talk about helpful, I'd love to see updates on the projects you make - feel free to drop those in the Discord server. 24 | 25 |
26 | 27 | ![The thumbnail image promo for the series](marketing/cover.png) 28 | 29 | -------------------------------------------------------------------------------- /SceneSwitcher.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=2] 2 | 3 | [ext_resource path="res://GrassLevel.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://SceneSwitcher.gd" type="Script" id=2] 5 | 6 | [sub_resource type="Animation" id=1] 7 | resource_name = "fade_in" 8 | tracks/0/type = "value" 9 | tracks/0/path = NodePath("OverlayLayer/Overlay:color") 10 | tracks/0/interp = 1 11 | tracks/0/loop_wrap = true 12 | tracks/0/imported = false 13 | tracks/0/enabled = true 14 | tracks/0/keys = { 15 | "times": PoolRealArray( 0.1, 1 ), 16 | "transitions": PoolRealArray( 1, 1 ), 17 | "update": 0, 18 | "values": [ Color( 0, 0, 0, 0 ), Color( 0, 0, 0, 1 ) ] 19 | } 20 | 21 | [sub_resource type="Animation" id=2] 22 | resource_name = "fade_out" 23 | tracks/0/type = "value" 24 | tracks/0/path = NodePath("OverlayLayer/Overlay:color") 25 | tracks/0/interp = 1 26 | tracks/0/loop_wrap = true 27 | tracks/0/imported = false 28 | tracks/0/enabled = true 29 | tracks/0/keys = { 30 | "times": PoolRealArray( 0, 1 ), 31 | "transitions": PoolRealArray( 1, 1 ), 32 | "update": 0, 33 | "values": [ Color( 0, 0, 0, 1 ), Color( 0, 0, 0, 0 ) ] 34 | } 35 | 36 | [node name="SceneSwitcher" type="Node"] 37 | script = ExtResource( 2 ) 38 | 39 | [node name="OverlayLayer" type="CanvasLayer" parent="."] 40 | layer = 10 41 | 42 | [node name="Overlay" type="ColorRect" parent="OverlayLayer"] 43 | anchor_right = 1.0 44 | anchor_bottom = 1.0 45 | margin_left = -0.535767 46 | margin_right = -0.535767 47 | mouse_filter = 2 48 | color = Color( 0, 0, 0, 0 ) 49 | __meta__ = { 50 | "_edit_use_anchors_": false 51 | } 52 | 53 | [node name="GrassLevel" parent="." instance=ExtResource( 1 )] 54 | 55 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."] 56 | anims/fade_in = SubResource( 1 ) 57 | anims/fade_out = SubResource( 2 ) 58 | [connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_AnimationPlayer_animation_finished"] 59 | -------------------------------------------------------------------------------- /DesertLevel.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://assets/raleway48.tres" type="DynamicFont" id=1] 4 | [ext_resource path="res://assets/raleway32.tres" type="DynamicFont" id=2] 5 | [ext_resource path="res://Level.gd" type="Script" id=3] 6 | [ext_resource path="res://assets/Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav" type="AudioStream" id=4] 7 | [ext_resource path="res://assets/Door-Bell-Ding-A1-www.fesliyanstudios.com.wav" type="AudioStream" id=5] 8 | 9 | [node name="DesertLevel" type="CanvasLayer"] 10 | script = ExtResource( 3 ) 11 | level_name = "desert" 12 | 13 | [node name="ColorRect" type="ColorRect" parent="."] 14 | anchor_right = 1.0 15 | anchor_bottom = 1.0 16 | margin_right = 500.0 17 | margin_bottom = 500.0 18 | rect_min_size = Vector2( 2000, 2000 ) 19 | color = Color( 0.94902, 0.87451, 0.380392, 1 ) 20 | __meta__ = { 21 | "_edit_use_anchors_": false 22 | } 23 | 24 | [node name="Label" type="Label" parent="."] 25 | anchor_left = 0.5 26 | anchor_top = 0.5 27 | anchor_right = 0.5 28 | anchor_bottom = 0.5 29 | margin_left = -170.0 30 | margin_top = -97.0 31 | margin_right = 170.0 32 | margin_bottom = -39.0 33 | custom_fonts/font = ExtResource( 1 ) 34 | text = "Desert Level" 35 | uppercase = true 36 | __meta__ = { 37 | "_edit_use_anchors_": false 38 | } 39 | 40 | [node name="ChangeSceneButton" type="Button" parent="."] 41 | anchor_left = 0.5 42 | anchor_top = 0.5 43 | anchor_right = 0.5 44 | anchor_bottom = 0.5 45 | margin_left = -115.0 46 | margin_top = -22.5 47 | margin_right = 115.0 48 | margin_bottom = 22.5 49 | custom_fonts/font = ExtResource( 2 ) 50 | disabled = true 51 | text = "Change Scene" 52 | __meta__ = { 53 | "_edit_use_anchors_": false 54 | } 55 | 56 | [node name="ClickLabel" type="Label" parent="."] 57 | anchor_left = 0.5 58 | anchor_top = 0.5 59 | anchor_right = 0.5 60 | anchor_bottom = 0.5 61 | margin_left = -155.257 62 | margin_top = 75.2698 63 | margin_right = 158.743 64 | margin_bottom = 133.27 65 | custom_fonts/font = ExtResource( 1 ) 66 | text = "Clicks: 0" 67 | align = 1 68 | uppercase = true 69 | __meta__ = { 70 | "_edit_use_anchors_": false 71 | } 72 | 73 | [node name="ClickButton" type="Button" parent="."] 74 | anchor_left = 0.5 75 | anchor_top = 0.5 76 | anchor_right = 0.5 77 | anchor_bottom = 0.5 78 | margin_left = -115.0 79 | margin_top = 151.5 80 | margin_right = 115.0 81 | margin_bottom = 196.5 82 | custom_fonts/font = ExtResource( 2 ) 83 | text = "Click Me!" 84 | __meta__ = { 85 | "_edit_use_anchors_": false 86 | } 87 | 88 | [node name="ButtonClickedSound" type="AudioStreamPlayer" parent="."] 89 | stream = ExtResource( 4 ) 90 | 91 | [node name="LevelLoadedSound" type="AudioStreamPlayer" parent="."] 92 | stream = ExtResource( 5 ) 93 | 94 | [connection signal="pressed" from="ChangeSceneButton" to="." method="_on_ChangeSceneButton_pressed"] 95 | [connection signal="pressed" from="ClickButton" to="." method="_on_ClickButton_pressed"] 96 | -------------------------------------------------------------------------------- /GrassLevel.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=6 format=2] 2 | 3 | [ext_resource path="res://assets/raleway48.tres" type="DynamicFont" id=1] 4 | [ext_resource path="res://assets/raleway32.tres" type="DynamicFont" id=2] 5 | [ext_resource path="res://Level.gd" type="Script" id=3] 6 | [ext_resource path="res://assets/Video-Game-Power-Level-Up-B1-www.fesliyanstudios.com (1).wav" type="AudioStream" id=4] 7 | [ext_resource path="res://assets/Door-Bell-Ding-A1-www.fesliyanstudios.com.wav" type="AudioStream" id=5] 8 | 9 | [node name="GrassLevel" type="CanvasLayer"] 10 | script = ExtResource( 3 ) 11 | level_name = "grass" 12 | 13 | [node name="ColorRect" type="ColorRect" parent="."] 14 | anchor_right = 1.0 15 | anchor_bottom = 1.0 16 | margin_right = 500.0 17 | margin_bottom = 500.0 18 | rect_min_size = Vector2( 2000, 2000 ) 19 | color = Color( 0.435294, 0.94902, 0.380392, 1 ) 20 | __meta__ = { 21 | "_edit_use_anchors_": false 22 | } 23 | 24 | [node name="Label" type="Label" parent="."] 25 | anchor_left = 0.5 26 | anchor_top = 0.5 27 | anchor_right = 0.5 28 | anchor_bottom = 0.5 29 | margin_left = -155.257 30 | margin_top = -98.7302 31 | margin_right = 158.743 32 | margin_bottom = -40.7302 33 | custom_fonts/font = ExtResource( 1 ) 34 | text = "Grass Level" 35 | uppercase = true 36 | __meta__ = { 37 | "_edit_use_anchors_": false 38 | } 39 | 40 | [node name="ChangeSceneButton" type="Button" parent="."] 41 | anchor_left = 0.5 42 | anchor_top = 0.5 43 | anchor_right = 0.5 44 | anchor_bottom = 0.5 45 | margin_left = -115.0 46 | margin_top = -22.5 47 | margin_right = 115.0 48 | margin_bottom = 22.5 49 | custom_fonts/font = ExtResource( 2 ) 50 | disabled = true 51 | text = "Change Scene" 52 | __meta__ = { 53 | "_edit_use_anchors_": false 54 | } 55 | 56 | [node name="ClickLabel" type="Label" parent="."] 57 | anchor_left = 0.5 58 | anchor_top = 0.5 59 | anchor_right = 0.5 60 | anchor_bottom = 0.5 61 | margin_left = -155.257 62 | margin_top = 75.2698 63 | margin_right = 158.743 64 | margin_bottom = 133.27 65 | custom_fonts/font = ExtResource( 1 ) 66 | text = "Clicks: 0" 67 | align = 1 68 | uppercase = true 69 | __meta__ = { 70 | "_edit_use_anchors_": false 71 | } 72 | 73 | [node name="ClickButton" type="Button" parent="."] 74 | anchor_left = 0.5 75 | anchor_top = 0.5 76 | anchor_right = 0.5 77 | anchor_bottom = 0.5 78 | margin_left = -115.0 79 | margin_top = 151.5 80 | margin_right = 115.0 81 | margin_bottom = 196.5 82 | custom_fonts/font = ExtResource( 2 ) 83 | text = "Click Me!" 84 | __meta__ = { 85 | "_edit_use_anchors_": false 86 | } 87 | 88 | [node name="ButtonClickedSound" type="AudioStreamPlayer" parent="."] 89 | stream = ExtResource( 4 ) 90 | 91 | [node name="LevelLoadedSound" type="AudioStreamPlayer" parent="."] 92 | stream = ExtResource( 5 ) 93 | 94 | [connection signal="pressed" from="ChangeSceneButton" to="." method="_on_ChangeSceneButton_pressed"] 95 | [connection signal="pressed" from="ClickButton" to="." method="_on_ClickButton_pressed"] 96 | --------------------------------------------------------------------------------