From 4a862d86f28140db119e3a8c767de8faa2469bb4 Mon Sep 17 00:00:00 2001 From: Daydreel Date: Thu, 21 Aug 2025 16:06:02 +0200 Subject: [PATCH] transition goto scene --- Assets/Shaders/transition.gdshader | 168 +++++++++++++++++++++++++ Assets/Shaders/transition.gdshader.uid | 1 + Globals/transition.gd | 56 +++++++++ Globals/transition.gd.uid | 1 + Globals/transition.tscn | 37 ++++++ UI/level_button.gd | 2 +- UI/level_button.tscn | 4 +- UI/start_menu.tscn | 87 +++++++++++-- default_theme.tres | 50 ++++++-- project.godot | 1 + 10 files changed, 385 insertions(+), 22 deletions(-) create mode 100644 Assets/Shaders/transition.gdshader create mode 100644 Assets/Shaders/transition.gdshader.uid create mode 100644 Globals/transition.gd create mode 100644 Globals/transition.gd.uid create mode 100644 Globals/transition.tscn diff --git a/Assets/Shaders/transition.gdshader b/Assets/Shaders/transition.gdshader new file mode 100644 index 0000000..6856c3b --- /dev/null +++ b/Assets/Shaders/transition.gdshader @@ -0,0 +1,168 @@ +shader_type canvas_item; + +uniform bool use_sprite_alpha = true; +uniform bool use_transition_texture = false; +uniform sampler2D transition_texture; +uniform int transition_type: hint_enum("Basic", "Mask", "Shape", "Clock") = 0; + +group_uniforms positioning; +uniform vec2 position = vec2(0,0); +uniform bool invert = false; +uniform vec2 grid_size = vec2(1.0, 1.0); +uniform float rotation_angle = 0.0; + +group_uniforms positioning.stagger; +uniform vec2 stagger = vec2(0.0, 0.0); +uniform ivec2 stagger_frequency = ivec2(2, 2); +uniform ivec2 flip_frequency = ivec2(1, 1); + +group_uniforms basic_transition_controls; +uniform float basic_feather = 0.0; + +group_uniforms mask_transition_controls; +uniform sampler2D mask_texture; +uniform bool use_mask_size = false; +uniform vec2 mask_size = vec2(100.0); + +group_uniforms shape_transition_controls; +uniform int edges : hint_range(3, 64) = 6; // default hexagon +uniform float shape_feather : hint_range(0.0, 10.0) = 0.1; + +group_uniforms clock_transition_controls; +uniform int sectors : hint_range(1, 128) = 1; +uniform float clock_feather : hint_range(0.0, 16.0) = 0.0; + +group_uniforms animation; +uniform float progress = 0.0; +uniform vec2 progress_bias = vec2(0.0); + +varying vec4 modulate; + +vec2 use_actual_texture_size(vec2 uv, vec2 texture_size) { + + uv -= 0.5; + vec2 uv_deriv = fwidth(uv); + float screen_ratio = uv_deriv.x / uv_deriv.y; + float texture_ratio = texture_size.x / texture_size.y; + float mixed_ratio = texture_ratio * screen_ratio; + + if (screen_ratio > texture_ratio) { + uv.x /= mixed_ratio; + } else { + uv.y *= mixed_ratio; + } + + return uv + 0.5; +} + +vec2 get_stagger_offset(vec2 grid) { + vec2 cells = floor(grid); + float offset_row = mod(cells.y, float(stagger_frequency.x)) == 0.0 ? 0.5 : 0.0; + float offset_col = mod(cells.x, float(stagger_frequency.y)) == 0.0 ? 0.5 : 0.0; + + return vec2( + offset_row * stagger.x, + offset_col * stagger.y + ); +} + +vec2 get_grid_flip(vec2 grid) { + vec2 cells = floor(grid); + float flip_row = mod(cells.y, float(flip_frequency.x)) == 0.0 ? 1.0 : -1.0; + float flip_col = mod(cells.x, float(flip_frequency.y)) == 0.0 ? 1.0 : -1.0; + + return vec2( + flip_row * grid.x, + flip_col * grid.y + ); +} + +vec2 rotate(vec2 v, float angle) { + return mat2( + vec2(cos(angle), sin(angle)), + vec2(-sin(angle), cos(angle)) + ) * v; +} + +vec2 get_edges(float center, float width) { + float half_width = width * 0.5; + float edge0 = center - half_width; + float edge1 = center + half_width + 1e-5; + return vec2(edge0, edge1); +} + +float get_local_progress(vec2 grid) { + vec2 cell = floor(grid); + // Easier to control bias values + vec2 pretty_bias = progress_bias / 10.0; + float offset = dot(cell, pretty_bias); + return progress - offset; +} + +void vertex() { + modulate = COLOR; +} + +void fragment() { + vec2 grid = UV * grid_size; + vec2 offset_uv = grid + get_stagger_offset(grid); + vec2 grid_flipped_uv = get_grid_flip(offset_uv); + vec2 tiled_uv = fract(grid_flipped_uv); + vec2 uv = (tiled_uv - position) * 2.0; + uv = rotate(uv, radians(rotation_angle)); + + float local_progress = get_local_progress(grid); + + COLOR = texture(TEXTURE, UV) * modulate; + float alpha = COLOR.a; + float transition_progress = 0.0; + + if (transition_type == 1) { + vec2 mask_zoom_uv = uv / local_progress; + vec2 mask_zoom_uv_01 = mask_zoom_uv * 0.5 + 0.5; + mask_zoom_uv_01 = use_mask_size ? use_actual_texture_size(mask_zoom_uv_01, mask_size) : mask_zoom_uv_01; + + transition_progress = texture(mask_texture, mask_zoom_uv_01).r; + + } else if(transition_type == 2) { + float radius = length(uv); + float angle = atan(uv.y, uv.x); + float sector_angle = 2.0 * PI / float(edges); + float half_sector = sector_angle / 2.0; + // Define polygon sectors using the power of trigonometry + float d = cos(half_sector) / cos(mod(angle + half_sector, sector_angle) - half_sector); + + vec2 smooth_edges = get_edges(local_progress, shape_feather); + transition_progress = smoothstep(smooth_edges.x, smooth_edges.y, radius / d); + + } else if (transition_type == 3) { + float radius = length(uv); + float angle = atan(uv.y, uv.x); + float sector_angle = 2.0 * PI / float(sectors); + float half_sector = sector_angle / 2.0; + angle = mod(angle - half_sector, sector_angle); + + float progress_angle = local_progress * 2.0 * PI / float(sectors); + float smooth_angle = smoothstep(0.0, clock_feather, progress_angle - angle); + transition_progress = smooth_angle; + + } else { + vec2 smooth_edges = get_edges(local_progress, basic_feather); + + float separation_x = smoothstep(smooth_edges.x, smooth_edges.y, abs(uv.x)); + float separation_y = smoothstep(smooth_edges.x, smooth_edges.y, abs(uv.y)); + transition_progress = max(separation_x, separation_y); + } + + alpha = invert ? 1.0 - transition_progress : transition_progress; + alpha = use_sprite_alpha ? min(COLOR.a, alpha) : alpha; + + vec4 transition_color = texture(transition_texture, UV); + + if (use_transition_texture) { + vec4 chosen_color = mix(transition_color, COLOR, alpha); + COLOR = chosen_color; + } else { + COLOR.a = alpha; + } +} \ No newline at end of file diff --git a/Assets/Shaders/transition.gdshader.uid b/Assets/Shaders/transition.gdshader.uid new file mode 100644 index 0000000..c61f9bc --- /dev/null +++ b/Assets/Shaders/transition.gdshader.uid @@ -0,0 +1 @@ +uid://c31b4mkeyaqhy diff --git a/Globals/transition.gd b/Globals/transition.gd new file mode 100644 index 0000000..749962d --- /dev/null +++ b/Globals/transition.gd @@ -0,0 +1,56 @@ +extends ColorRect + +@export var opaque := 0.0 +@export var transparent := 11.0 +var duration := 1.0 + +var target_scene_path : String + +var loading_status : int +var progress : Array[float] + +var tween : Tween + +func goto(scene_path : String): + target_scene_path = scene_path + + fade_in() + tween.tween_callback(load_scene) + + + +func load_scene() -> void: + ResourceLoader.load_threaded_request(target_scene_path) #Fetch loading status and loading scene + +func animate() -> void: + if tween: + tween.kill() # Abort the previous animation. + tween = create_tween() + +func fade_in() -> void: + animate() + tween.tween_method(shader_transition, transparent, opaque, duration) + +func fade_out() -> void: + animate() + tween.tween_method(shader_transition, opaque, transparent, duration) + +func shader_transition(value) -> void: + material.set_shader_parameter("progress", value) + +func _process(_delta: float) -> void: + # Update the status: + loading_status = ResourceLoader.load_threaded_get_status(target_scene_path, progress) + + # Check the loading status: + match loading_status: + ResourceLoader.THREAD_LOAD_IN_PROGRESS: + pass + ResourceLoader.THREAD_LOAD_LOADED: + # When done loading, change to the target scene: + get_tree().change_scene_to_packed(ResourceLoader.load_threaded_get(target_scene_path)) + fade_out() + pass + ResourceLoader.THREAD_LOAD_FAILED: + # Well some error happend: + printerr("Error. Could not load Resource") diff --git a/Globals/transition.gd.uid b/Globals/transition.gd.uid new file mode 100644 index 0000000..f243fed --- /dev/null +++ b/Globals/transition.gd.uid @@ -0,0 +1 @@ +uid://d1s1axal8vmdn diff --git a/Globals/transition.tscn b/Globals/transition.tscn new file mode 100644 index 0000000..f0632da --- /dev/null +++ b/Globals/transition.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=4 format=3 uid="uid://csdix1ygo386u"] + +[ext_resource type="Shader" uid="uid://c31b4mkeyaqhy" path="res://Assets/Shaders/transition.gdshader" id="1_inf52"] +[ext_resource type="Script" uid="uid://d1s1axal8vmdn" path="res://Globals/transition.gd" id="2_x2rwd"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_2cbuu"] +shader = ExtResource("1_inf52") +shader_parameter/use_sprite_alpha = true +shader_parameter/use_transition_texture = false +shader_parameter/transition_type = 2 +shader_parameter/position = Vector2(0, 0) +shader_parameter/invert = false +shader_parameter/grid_size = Vector2(50, 30) +shader_parameter/rotation_angle = 0.0 +shader_parameter/stagger = Vector2(0, 0) +shader_parameter/stagger_frequency = Vector2i(2, 2) +shader_parameter/flip_frequency = Vector2i(1, 1) +shader_parameter/basic_feather = 0.0 +shader_parameter/use_mask_size = false +shader_parameter/mask_size = Vector2(100, 100) +shader_parameter/edges = 4 +shader_parameter/shape_feather = 0.0 +shader_parameter/sectors = 1 +shader_parameter/clock_feather = 0.0 +shader_parameter/progress = 11.0 +shader_parameter/progress_bias = Vector2(1, 1) + +[node name="Transition" type="ColorRect"] +z_index = 1000 +material = SubResource("ShaderMaterial_2cbuu") +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0, 0, 0, 1) +script = ExtResource("2_x2rwd") diff --git a/UI/level_button.gd b/UI/level_button.gd index fa736b2..4f977c3 100644 --- a/UI/level_button.gd +++ b/UI/level_button.gd @@ -4,4 +4,4 @@ class_name LevelButton @export_file("*.tscn") var level : String func _on_pressed() -> void: - get_tree().change_scene_to_file(level) + Transition.goto(level) diff --git a/UI/level_button.tscn b/UI/level_button.tscn index dd30b20..3effe2a 100644 --- a/UI/level_button.tscn +++ b/UI/level_button.tscn @@ -1,8 +1,10 @@ -[gd_scene load_steps=2 format=3 uid="uid://88elnilxithv"] +[gd_scene load_steps=3 format=3 uid="uid://88elnilxithv"] [ext_resource type="Script" uid="uid://cudalakmyqm04" path="res://UI/level_button.gd" id="1_k6cd2"] +[ext_resource type="Theme" uid="uid://bbp4qcbwkeg7x" path="res://default_theme.tres" id="1_rdmfi"] [node name="Level1Button" type="Button"] +theme = ExtResource("1_rdmfi") text = "Level 1" script = ExtResource("1_k6cd2") diff --git a/UI/start_menu.tscn b/UI/start_menu.tscn index 78485f4..658e97a 100644 --- a/UI/start_menu.tscn +++ b/UI/start_menu.tscn @@ -1,12 +1,35 @@ -[gd_scene load_steps=9 format=3 uid="uid://2xw1yn1tmlcy"] +[gd_scene load_steps=11 format=3 uid="uid://2xw1yn1tmlcy"] [ext_resource type="PackedScene" uid="uid://88elnilxithv" path="res://UI/level_button.tscn" id="1_dl586"] [ext_resource type="Script" uid="uid://dqtxbncmls4tu" path="res://UI/start_menu.gd" id="1_neu3s"] [ext_resource type="PackedScene" uid="uid://c6hg12tui8344" path="res://VFX/pixel_rain.tscn" id="1_q5qyg"] +[ext_resource type="Shader" uid="uid://c31b4mkeyaqhy" path="res://Assets/Shaders/transition.gdshader" id="1_yqwmv"] [ext_resource type="FontFile" uid="uid://dvcx4cv7ge60n" path="res://Assets/Fonts/Grandstander/static/Grandstander-SemiBold.ttf" id="2_f14c5"] [ext_resource type="Texture2D" uid="uid://cs24awnya7o5p" path="res://Assets/VFX/start_menu_vignette.png" id="2_j3hi8"] [ext_resource type="Theme" uid="uid://bbp4qcbwkeg7x" path="res://default_theme.tres" id="6_rcgl7"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_2cbuu"] +shader = ExtResource("1_yqwmv") +shader_parameter/use_sprite_alpha = true +shader_parameter/use_transition_texture = false +shader_parameter/transition_type = 2 +shader_parameter/position = Vector2(0, 0) +shader_parameter/invert = false +shader_parameter/grid_size = Vector2(50, 30) +shader_parameter/rotation_angle = 0.0 +shader_parameter/stagger = Vector2(0, 0) +shader_parameter/stagger_frequency = Vector2i(2, 2) +shader_parameter/flip_frequency = Vector2i(1, 1) +shader_parameter/basic_feather = 0.0 +shader_parameter/use_mask_size = false +shader_parameter/mask_size = Vector2(100, 100) +shader_parameter/edges = 4 +shader_parameter/shape_feather = 0.0 +shader_parameter/sectors = 1 +shader_parameter/clock_feather = 0.0 +shader_parameter/progress = 11.0 +shader_parameter/progress_bias = Vector2(1, 1) + [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_f14c5"] bg_color = Color(0.933333, 0.933333, 0.933333, 1) @@ -18,6 +41,7 @@ shadow_size = 3 shadow_offset = Vector2(0, 0) [node name="StartMenu" type="Control"] +material = SubResource("ShaderMaterial_2cbuu") layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -31,9 +55,16 @@ script = ExtResource("1_neu3s") [node name="Camera2D" type="Camera2D" parent="Node2D"] position = Vector2(960, 540) -[node name="Background" type="CanvasLayer" parent="."] +[node name="Background" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="Panel" type="Panel" parent="Background"] +layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 @@ -41,7 +72,13 @@ grow_horizontal = 2 grow_vertical = 2 theme_override_styles/panel = SubResource("StyleBoxFlat_f14c5") -[node name="Layer1" type="CanvasLayer" parent="."] +[node name="Layer1" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="VFX" type="Node2D" parent="Layer1"] @@ -52,6 +89,7 @@ trail_lifetime = 1.0 overall_scale = 0.18 [node name="ColorRect" type="ColorRect" parent="Layer1"] +layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 @@ -59,7 +97,13 @@ grow_horizontal = 2 grow_vertical = 2 color = Color(1, 1, 1, 0.470588) -[node name="Layer2" type="CanvasLayer" parent="."] +[node name="Layer2" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="VFX" type="Node2D" parent="Layer2"] @@ -70,6 +114,7 @@ trail_lifetime = 1.15 overall_scale = 0.23 [node name="ColorRect" type="ColorRect" parent="Layer2"] +layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 @@ -77,7 +122,13 @@ grow_horizontal = 2 grow_vertical = 2 color = Color(1, 1, 1, 0.313726) -[node name="Layer3" type="CanvasLayer" parent="."] +[node name="Layer3" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="VFX" type="Node2D" parent="Layer3"] @@ -88,6 +139,7 @@ trail_lifetime = 1.3 overall_scale = 0.28 [node name="ColorRect" type="ColorRect" parent="Layer3"] +layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 @@ -95,10 +147,17 @@ grow_horizontal = 2 grow_vertical = 2 color = Color(1, 1, 1, 0.156863) -[node name="Layer4" type="CanvasLayer" parent="."] +[node name="Layer4" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="Vignette" type="TextureRect" parent="Layer4"] modulate = Color(1, 1, 1, 0.521569) +layout_mode = 0 offset_right = 1920.0 offset_bottom = 1080.0 texture = ExtResource("2_j3hi8") @@ -109,9 +168,16 @@ texture = ExtResource("2_j3hi8") lifetime = 10.0 overall_scale = 0.33 -[node name="Middleground" type="CanvasLayer" parent="."] +[node name="Middleground" type="Control" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="Label" type="Label" parent="Middleground"] +layout_mode = 1 anchors_preset = 5 anchor_left = 0.5 anchor_right = 0.5 @@ -126,6 +192,7 @@ label_settings = SubResource("LabelSettings_j3hi8") horizontal_alignment = 1 [node name="VBoxContainer" type="VBoxContainer" parent="Middleground"] +layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 @@ -137,16 +204,12 @@ offset_right = 91.0 offset_bottom = 47.0 grow_horizontal = 2 grow_vertical = 2 +theme_override_constants/separation = 20 [node name="Level1Button" parent="Middleground/VBoxContainer" instance=ExtResource("1_dl586")] layout_mode = 2 -theme = ExtResource("6_rcgl7") level = "uid://ky0uewndeuwv" -[node name="MarginContainer" type="MarginContainer" parent="Middleground/VBoxContainer"] -custom_minimum_size = Vector2(0, 60) -layout_mode = 2 - [node name="QuitButton" type="Button" parent="Middleground/VBoxContainer"] layout_mode = 2 theme = ExtResource("6_rcgl7") diff --git a/default_theme.tres b/default_theme.tres index 14c299a..9712d24 100644 --- a/default_theme.tres +++ b/default_theme.tres @@ -1,22 +1,56 @@ -[gd_resource type="Theme" load_steps=3 format=3 uid="uid://bbp4qcbwkeg7x"] +[gd_resource type="Theme" load_steps=6 format=3 uid="uid://bbp4qcbwkeg7x"] [ext_resource type="FontFile" uid="uid://dcrwvx1qpvwx0" path="res://Assets/Fonts/Glass_Antiqua/GlassAntiqua-Regular.ttf" id="1_e7bfs"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_50bnw"] +content_margin_left = 30.0 +content_margin_top = 20.0 +content_margin_right = 30.0 +content_margin_bottom = 20.0 +bg_color = Color(0.882353, 0.243137, 0.14902, 1) +draw_center = false +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_e7bfs"] +content_margin_left = 30.0 +content_margin_top = 20.0 +content_margin_right = 30.0 +content_margin_bottom = 20.0 +bg_color = Color(0.882353, 0.243137, 0.14902, 1) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 + [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7j863"] +content_margin_left = 30.0 +content_margin_top = 20.0 +content_margin_right = 30.0 +content_margin_bottom = 20.0 bg_color = Color(0.2, 0.2, 0.2, 1) border_width_left = 1 border_width_top = 1 border_width_right = 1 border_width_bottom = 1 -expand_margin_left = 10.0 -expand_margin_top = 20.0 -expand_margin_right = 10.0 -expand_margin_bottom = 20.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3taad"] +content_margin_left = 30.0 +content_margin_top = 20.0 +content_margin_right = 30.0 +content_margin_bottom = 20.0 +bg_color = Color(0.333333, 0.333333, 0.333333, 1) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 [resource] default_font = ExtResource("1_e7bfs") default_font_size = 40 -Button/styles/focus = SubResource("StyleBoxFlat_7j863") -Button/styles/hover = SubResource("StyleBoxFlat_7j863") +Button/styles/focus = SubResource("StyleBoxFlat_50bnw") +Button/styles/hover = SubResource("StyleBoxFlat_e7bfs") Button/styles/normal = SubResource("StyleBoxFlat_7j863") -Button/styles/pressed = SubResource("StyleBoxFlat_7j863") +Button/styles/pressed = SubResource("StyleBoxFlat_3taad") diff --git a/project.godot b/project.godot index 7e2b831..c2c9974 100644 --- a/project.godot +++ b/project.godot @@ -19,6 +19,7 @@ config/icon="res://icon.svg" GameManager="*res://Globals/GameManager.gd" EventBus="*res://Globals/EventBus.gd" +Transition="*res://Globals/transition.tscn" [display]