Skip to content

Transitions

Charles edited this page Jun 14, 2026 · 4 revisions

Introduction

ProtoJam provides a general purpose transitions framework suitable both for swapping scenes behind a loading screen and transitioning elements within a scene; additionally, two commonly used transition types are provided: a simple fade and a luminance mask.

Using NodeSwapper

The NodeSwapper is the core of the transition framework. This node dynamically changes its children while a transition plays. Rather than using Node.add_child, the child of a node wrapper is changed using a call to either transition_to_scene or the more general transition_to.

The transition_to_scene method accepts a path or UID to a packed scene and loads it in the background during the transition:

var _node_swapper: NodeSwapper = %NodeSwapper

func _ready() -> void:
	_node_swapper.transition_to_scene("res://level_1.tscn")

An optional initializer coroutine may also be passed to initialize the loaded scene or connect signals before it is added to the tree:

var _node_swapper: NodeSwapper = %NodeSwapper

func _ready() -> void:
	var content_initializer: Callable = func(content: Node) -> void:
		content.some_property = # ...
		content.some_signal.connect(...)
	
	_node_swapper.transition_to_scene("res://level_1.tscn", content_initializer)

The transition_to method is similar but instead takes a coroutine which it will invoke during the transition to obtain its node:

var _node_swapper: NodeSwapper = %NodeSwapper

func _ready() -> void:
	var content_provider: Callable = func() -> Node:
		var content: Node3D = Node3D.new()
		# ...
		return content
	
	_node_swapper.transition_to(content_provider)

Both transition functions accept an optional ready coroutine that will be called when the node has been added to the tree:

var _node_swapper: NodeSwapper = %NodeSwapper

func _ready() -> void:
	var content_initializer: Callable = func(content: Node) -> void:
		content.some_property = # ...
		content.some_signal.connect(...)
	
	
	var content_ready: Callable = func(content: Node) -> void:
		content.some_property = # ...
	
	_node_swapper.transition_to_scene("res://level_1.tscn", content_initializer, content_ready)

A default transition provider can be set on the node swapper but can be overridden by either transition method:

var _node_swapper: NodeSwapper = %NodeSwapper

func _ready() -> void:
	_node_swapper.transition_provider = LuminanceMaskTransitionProvider.new()
	
	var content_initializer: Callable = func(content: Node) -> void:
		content.some_property = # ...
		content.some_signal.connect(...)
	
	
	var content_ready: Callable = func(content: Node) -> void:
		content.some_property = # ...
	
	_node_swapper.transition_to_scene("res://level_1.tscn", content_initializer, content_ready, FadeTransitionProvider.new())

The is_transitioning method and transitioned signal can be used to monitor the state of the transition.

var _node_swapper: NodeSwapper = %NodeSwapper

func _ready() -> void:
	_node_swapper.transitioned.connect(_on_transitioned)
	_node_swapper.transition_to_scene("res://level_1.tscn")


func _process(_delta: float) -> void:
	if _node_swapper.is_transitioning():
		# Do something while transitioning


func _on_transitioned(content: Node) -> void:
	# Do something with newly transitioned content

Using AbstractTransition

Every transition must inherit from AbstractTransition to be used by NodeSwapper. This requires implementing _start_transition_in and _start_transition_out. Additionally, custom implementations must call _end_transition_in and _start_transition_out respectively to indicate when a transition is complete.

ProtoJam provides FadeTransition and LuminanceMaskTransition as examples of commonly used transitions.

Using AbstractTransitionProvider

An AbstractTransitionProvider is an abstraction used by NodeSwapper to obtain instances of AbstractTransition preconfigured with any user settings. In most cases, the provider will export several settings users can tweak to control the transition's behavior. When invoked, it will then construct a new transition, apply the settings, and return it; however, there is no strict requirement that a provider always return a new instance.

🚧 WIP

  • FadeTransitionProvider
  • LuminanceMaskTransitionProvider

Examples

Example 1 - Custom transition

🚧 WIP

Clone this wiki locally