Transitions were actually easier than I thought they would be. Consists basically of a Camera2D node, which constantly checks to see if the player has moved off screen. If so, snap to the nearest "window".
extends Camera2D var is_moving = false func _process(delta): var pos = get_node("../Player").global_position - Vector2(0, 16) var x = floor(pos.x / 320) * 320 var y = floor(pos.y / 180) * 180 if self.global_position != Vector2(x, y) and is_moving == false: is_moving = true get_tree().paused = true $Tween.interpolate_property(self, "global_position", self.global_position, Vector2(x, y), 0.5, Tween.TRANS_LINEAR) $Tween.start() yield($Tween, "tween_completed") get_tree().paused = false is_moving = false