Skip to content

Commit

Permalink
v0.4.0: code cleanup, new API methods, new options
Browse files Browse the repository at this point in the history
  • Loading branch information
jabsatz committed Apr 8, 2022
1 parent 59d5825 commit 96952c5
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 133 deletions.
64 changes: 48 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,27 +61,23 @@ The `path` paremeter accepts an absolute file path for your new scene (i.e: 'res

You can pass the following options to this function in a dictionary:

- `type : FadeTypes = (inferred from options, default is Fade)`: Style of the transition. `Fade` is a simple fade-to-black transition, while `ShaderFade` will use a black-and-white image to represent each pixel, allowing for custom transitions.
- `speed : float = 2`: Speed of the moving transition.
- `color : Color = Color('#000000')`: Color to use for the transition screen. It's black by default.
- `wait_time : float = 0.5`: Time spent in the transition screen while switching scenes. Leaving it at 0 with fade will result in the screen not turning black, so it waits a little bit by default.
- `no_scene_change : Bool = false`: If set to true, it will not change or reload the scene once the fade is complete

The following options are only used when using a `ShaderFade`. If any of them are declared without providing a `"type"`, it will be inferred as `ShaderFade`.

- `pattern : (String || Texture) = 'squares'`: Pattern to use for the transition. Using a simple name will load the premade patterns we have designed (you can see them in `addons/scene_manager/shader_patterns`). Otherwise, you may pass an absolute path to your own pattern `"res://my_pattern.png"` or a `Texture` object.
- `skip_scene_change : Bool = false`: If set to true, skips the actual scene change/reload, leaving only the transition.
- `skip_fade_out : Bool = false`: If set to true, skips the initial "fade" part of the transition
- `skip_fade_in : Bool = false`: If set to true, skips the final "fade" part of the transition
- `pattern : (String || Texture) = 'fade'`: Pattern to use for the transition. Using a simple name will load the premade patterns we have designed (you can see them in `addons/scene_manager/shader_patterns`). Otherwise, you may pass an absolute path to your own pattern `"res://my_pattern.png"` or a `Texture` object. You can also specify `'fade'` for a simple fade transition.
- `pattern_enter : (String || Texture) = pattern`: Same as `pattern`, but overrides the pattern only for the fade-to-black transition.
- `pattern_leave : (String || Texture) = pattern`: Same as `pattern`, but overrides the pattern only for the fade-from-black transition.

- `shader_pattern`, `shader_pattern_enter` and `shader_pattern_leave` were the old names for these options, they will still work but have been deprecated.

- `invert_on_leave : Bool = true`: Wether the transition should invert when fading out of black. This usually looks better on, the effect is that the first pixels that turned black are the first ones that fade into the new screen. This generally works for "sweep" transitions like `"horizontal"`, but others such as `"curtains"` might look better with this flag turned off
- `ease : (float || Bool) = 1.0`: Amount of ease the animation should have during the transition. For backwards compatibility, `true` becomes `0.5` and `false` becomes `1.0`.
- `ease_enter : (float || Bool) = ease`: Amount of ease the animation should have during the fade-to-black transition.
- `ease_leave : (float || Bool) = ease`: Amount of ease the animation should have during the fade-from-black transition.
- `ease : float = 1.0`: Amount of ease the animation should have during the transition.
- `ease_enter : float = ease`: Amount of ease the animation should have during the fade-to-black transition.
- `ease_leave : float = ease`: Amount of ease the animation should have during the fade-from-black transition.

The following patterns are available out-of-the-box:

- `"fade"`
- `"circle"`
- `"curtains"`
- `"diagonal"`
Expand All @@ -101,6 +97,35 @@ Of note, is that this method will not trigger the `scene_unloaded` signal, since

This method functions exactly like `reload_scene({ "no_scene_change": true })`, it will simply trigger the transition used in options, without modifying anything. You can use the `fade_complete` signal if you want to change something while the screen is completely black.

### `func fade_out(options: Dictionary = defaultOptions)`

This method fades out the screen, useful when you want to fade to black and do some calculations/processing manually. Works well in conjunction with the `"skip_fade_out"` option.

```
yield (SceneManager.fade_out(), "completed")
// Do something
SceneManager.change_scene(new_scene, { "skip_fade_out": true })
```

It can take the following options, with the same defaults as `change_scene`:

- `speed`
- `color`
- `pattern`
- `ease`

### `func fade_in(options: Dictionary = defaultOptions)`

This method fades in the screen, useful to do if you want an initial transition when opening the game.

It can take the following options, with the same defaults as `change_scene`:

- `speed`
- `color`
- `pattern`
- `invert_on_leave`
- `ease`

### `func get_entity(entity_name: String)`

Get a reference to a named entity (node) in your scene. To define entity names go to the desired node in the editor inspector and you'll see two new properties: `Singleton entity` and `Entity name`. Check the `Singleton entity` checkbox to have this node saved to the SceneManager entity dictionary and write a friendly `Entity name` to be used in this function. Afterwards, you'll be able to access it within the scene.
Expand All @@ -116,13 +141,20 @@ Player = SceneManager.get_entity("Player")

This variable changes depending of wether a transition is active or not. You can use this to make sure a transition is finished before starting a new one if the `transition_finished` signal does not suit your use-case.

### `FadeTypes`

SceneManager defines this enum: `FadeTypes { Fade, ShaderFade }`. It can be accessed via `SceneManager.FadeTypes.Fade`

### Signals

- `scene_unloaded`: emitted when the first scene is unloaded
- `scene_loaded`: emitted when the new scene is loaaded
- `fade_complete`: emitted when the fade-to-black animation finishes
- `transition_finished`: emitted when the transition finishes

# Deprecation warnings

The following deprecation warnings are in effect. These features may still work, but will be removed in the future. If you use any of the features below, please follow the instructions:

- `type` option and `FadeTypes` enum: **remove entirely**. For normal fade transitions, use `"pattern": "fade"`.
- `shader_pattern` option: replace for `pattern`
- `shader_pattern_enter` option: replace for `pattern_enter`
- `shader_pattern_leave` option: replace for `pattern_leave`
- `no_scene_change` option: replace for `skip_scene_change`
- `ease`, `ease_enter`, `ease_leave` options: do not use `bool` values. Replace `true -> 0.5` and `false -> 1.0`.
12 changes: 0 additions & 12 deletions addons/scene_manager/ColorFade.tres
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,3 @@

[resource]
resource_name = "Fade"
tracks/0/type = "value"
tracks/0/path = NodePath("CanvasLayer/Fade:color")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 1 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Color( 0, 0, 0, 0 ), Color( 0, 0, 0, 1 ) ]
}
9 changes: 5 additions & 4 deletions addons/scene_manager/Dissolve2d.shader
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
shader_type canvas_item;

uniform sampler2D dissolve_texture;
uniform float dissolve_amount : hint_range(0, 1);
uniform vec4 fade_color;
uniform bool inverted;
uniform float dissolve_amount : hint_range(0.0, 1.0) = 0.5;
uniform vec4 fade_color : hint_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform bool fade = false;
uniform bool inverted = false;

void fragment() {
if (dissolve_amount == 0.0 || dissolve_amount == 1.0) {
if (dissolve_amount < 0.0001 || dissolve_amount > 0.9999 || fade) {
COLOR = vec4(fade_color.rgb, dissolve_amount);
} else {
float sample = texture(dissolve_texture, UV).r;
Expand Down
146 changes: 63 additions & 83 deletions addons/scene_manager/SceneManager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -10,54 +10,46 @@ onready var _tree := get_tree()
onready var _root := _tree.get_root()
onready var _current_scene := _tree.current_scene
onready var _animation_player := $AnimationPlayer
onready var _fade_rect := $CanvasLayer/Fade
onready var _shader_blend_rect := $CanvasLayer/ShaderFade
onready var _shader_blend_rect := $CanvasLayer/ColorRect

enum FadeTypes { Fade, ShaderFade }

var default_options = {
"type": FadeTypes.Fade,
var default_options := {
"speed": 2,
"color": Color("#000000"),
"pattern": "squares",
"pattern": "fade",
"wait_time": 0.5,
"invert": false,
"invert_on_leave": true,
"ease": 1.0,
"no_scene_change": false,
"skip_scene_change": false,
"skip_fade_out": false,
"skip_fade_in": false,
}
# extra_options = {
# "pattern_enter": DEFAULT_IMAGE,
# "pattern_leave": DEFAULT_IMAGE,
# "ease_enter": true,
# "ease_leave": true,
# "ease_enter": 1.0,
# "ease_leave": 1.0,
# }

var new_names = {
var new_names := {
"shader_pattern": "pattern",
"shader_pattern_enter": "pattern_enter",
"shader_pattern_leave": "pattern_leave"
"shader_pattern_leave": "pattern_leave",
"no_scene_change": "skip_scene_change",
}

var shader_exclusive_keys = [
"pattern",
"pattern_enter",
"pattern_leave",
"invert_on_leave",
"ease",
"ease_enter",
"ease_leave",
]

var singleton_entities = {}
var singleton_entities := {}
var _previous_scene = null


func _ready():
func _ready() -> void:
_set_singleton_entities()
call_deferred("emit_signal", "scene_loaded")
call_deferred("emit_signal", "transition_finished")


func _set_singleton_entities():
func _set_singleton_entities() -> void:
singleton_entities = {}
var entities = _current_scene.get_tree().get_nodes_in_group(
SceneManagerConstants.SINGLETON_GROUP_NAME
Expand All @@ -82,37 +74,32 @@ func _set_singleton_entities():
singleton_entities[entity_name] = entity


func get_entity(entity_name: String):
func get_entity(entity_name: String) -> Node:
assert(
singleton_entities.has(entity_name),
"Entity %s is not set as a singleton entity. Please define it in the editor." % entity_name
)
return singleton_entities[entity_name]


func _load_pattern(pattern):
func _load_pattern(pattern) -> Texture:
assert(
pattern is Texture or pattern is String,
"Pattern %s is not a valid Texture, absolute path, or built-in texture." % pattern
)

if pattern is String:
if pattern.is_abs_path():
return load(pattern)
return load("res://addons/scene_manager/shader_patterns/%s.png" % pattern)
return load(pattern) as Texture
elif pattern == "fade":
return null
return load("res://addons/scene_manager/shader_patterns/%s.png" % pattern) as Texture
return pattern


func _get_final_options(initial_options: Dictionary):
func _get_final_options(initial_options: Dictionary) -> Dictionary:
var options = initial_options.duplicate()

if not "type" in initial_options:
var inferred_type = FadeTypes.Fade
for key in shader_exclusive_keys:
if initial_options.has(key):
inferred_type = FadeTypes.ShaderFade
options["type"] = inferred_type

for key in options:
if new_names.has(key):
var new_key = new_names[key]
Expand All @@ -138,10 +125,7 @@ func _get_final_options(initial_options: Dictionary):
return options


var _previous_scene = null


func _process(_delta):
func _process(_delta: float) -> void:
if not is_instance_valid(_previous_scene) and _tree.current_scene:
_previous_scene = _tree.current_scene
_current_scene = _tree.current_scene
Expand All @@ -151,31 +135,36 @@ func _process(_delta):
_previous_scene = _tree.current_scene


func change_scene(path, setted_options: Dictionary = {}):
func change_scene(path, setted_options: Dictionary = {}) -> void:
var options = _get_final_options(setted_options)
yield(_fade_out(options), "completed")
if not options["no_scene_change"]:
_replace_scene(path)
if not options["skip_fade_out"]:
yield(fade_out(setted_options), "completed")
if not options["skip_scene_change"]:
if path == null:
_reload_scene()
else:
_replace_scene(path)
yield(_tree.create_timer(options["wait_time"]), "timeout")
yield(_fade_in(options), "completed")
if not options["skip_fade_in"]:
yield(fade_in(setted_options), "completed")


func reload_scene(setted_options: Dictionary = {}):
func reload_scene(setted_options: Dictionary = {}) -> void:
yield(change_scene(null, setted_options), "completed")


func fade_in_place(setted_options: Dictionary = {}):
setted_options["no_scene_change"] = true
func fade_in_place(setted_options: Dictionary = {}) -> void:
setted_options["skip_scene_change"] = true
yield(change_scene(null, setted_options), "completed")


func _replace_scene(path):
if path == null:
# if no path, assume we want a reload
_tree.reload_current_scene()
yield(_tree.create_timer(0.0), "timeout")
_current_scene = _tree.current_scene
return
func _reload_scene() -> void:
_tree.reload_current_scene()
yield(_tree.create_timer(0.0), "timeout")
_current_scene = _tree.current_scene


func _replace_scene(path: String) -> void:
_current_scene.free()
emit_signal("scene_unloaded")
var following_scene = ResourceLoader.load(path)
Expand All @@ -185,42 +174,33 @@ func _replace_scene(path):
_tree.set_current_scene(_current_scene)


func _fade_out(options):
func fade_out(setted_options: Dictionary = {}) -> void:
var options = _get_final_options(setted_options)
is_transitioning = true
_animation_player.playback_speed = options["speed"]

match options["type"]:
FadeTypes.Fade:
_fade_rect.color = options["color"]
_animation_player.play("ColorFade")

FadeTypes.ShaderFade:
_shader_blend_rect.material.set_shader_param(
"dissolve_texture", options["pattern_enter"]
)
_shader_blend_rect.material.set_shader_param("fade_color", options["color"])
_shader_blend_rect.material.set_shader_param("inverted", false)
var animation = _animation_player.get_animation("ShaderFade")
animation.track_set_key_transition(0, 0, options["ease_enter"])
_animation_player.play("ShaderFade")
_shader_blend_rect.material.set_shader_param("dissolve_texture", options["pattern_enter"])
_shader_blend_rect.material.set_shader_param("fade", not options["pattern_enter"])
_shader_blend_rect.material.set_shader_param("fade_color", options["color"])
_shader_blend_rect.material.set_shader_param("inverted", options["invert"])
var animation = _animation_player.get_animation("ShaderFade")
animation.track_set_key_transition(0, 0, options["ease_enter"])
_animation_player.play("ShaderFade")

yield(_animation_player, "animation_finished")
emit_signal("fade_complete")


func _fade_in(options):
match options["type"]:
FadeTypes.Fade:
_animation_player.play_backwards("ColorFade")

FadeTypes.ShaderFade:
_shader_blend_rect.material.set_shader_param(
"dissolve_texture", options["pattern_leave"]
)
_shader_blend_rect.material.set_shader_param("inverted", options["invert_on_leave"])
var animation = _animation_player.get_animation("ShaderFade")
animation.track_set_key_transition(0, 0, options["ease_leave"])
_animation_player.play_backwards("ShaderFade")
func fade_in(setted_options: Dictionary = {}) -> void:
var options = _get_final_options(setted_options)
_shader_blend_rect.material.set_shader_param("dissolve_texture", options["pattern_leave"])
_shader_blend_rect.material.set_shader_param("fade", not options["pattern_leave"])
_shader_blend_rect.material.set_shader_param(
"inverted", not options["invert"] if options["invert_on_leave"] else options["invert"]
)
var animation = _animation_player.get_animation("ShaderFade")
animation.track_set_key_transition(0, 0, options["ease_leave"])
_animation_player.play_backwards("ShaderFade")

yield(_animation_player, "animation_finished")
is_transitioning = false
Expand Down
Loading

0 comments on commit 96952c5

Please sign in to comment.