MeteorCat / 场景过渡

Created Mon, 04 Mar 2024 17:45:14 +0800 Modified Wed, 29 Oct 2025 23:24:59 +0800

场景过渡

最近在制作游戏过程之中碰到就是场景要过渡切换到另外另外场景, 在单机游戏和网络游戏当中场景切换应对方式感觉有所不同:

  • 单机游戏: 常见开源项目场景切换都是直接无状态重载场景, 之后加载本地保存的数据
  • 网络游戏: 所有场景优先加载到场景隐藏, 之后根据需要切换指定场景显示, 所有场景都不会释放而是采用隐藏处理.

在这种过程之中, 常常纠结于去怎么实现, 像 Godot 单机方面直接 SceneManagent 那样直接切换这种情况是不需要说明, 主要最近像开发 H5 品类的网络游戏, 一直在思考怎么做到状态维持的网络游戏转场切换.

读取场景是在当前场景还是之后场景? 场景黑屏切换过渡场景要求下个场景需要有相同的黑屏切换保持切换状态.

原场景切换

这里面的是需要保证场景A和场景B过渡场景都需要保持一致, 也就是场景A在黑屏读条准备加载场景B的过程之中, 这种情况要求所有被切换都要求先做好场景铺垫.

之后就是另外默认场景带有黑屏方式做转换:

原场景切换

这里把过渡放置在需要切换的场景, 默认 show 的时候自带黑屏读条等待初始化之后等待去展示.

这种切换方式其实更灵活点, 这样把切换加载读条逻辑转移到所在场景处理, 而且不会出现因为上个场景和当前场景冲突.

前置场景加载并非一无是处, 比如需要启动的时候动态加载所有资源的情况; 有的关卡需要常驻加载大场景的情况, 这时候就需要专门做过渡场景来处理.

在随机性大地图等动态地图情况就需要这样在切换成读条来动态构建地图, 这种构建过程的时间就需要动态创建场景之后附加到节点之后等待完成展示.

这里追加个 ColorRect 的颜色渐变样例:

'''
基于 ColorRect 颜色区块做的淡入淡出功能
'''
extends ColorRect
class_name Fade

'''
默认初始化隐藏状态
'''
@export var is_hidden:bool = false

'''
淡入淡出的速度
'''
@export var speed:float = 1


'''
是否还在执行切换
'''
var _running:bool = false


'''
确定是否淡入还是淡出
'''
var _use_fade_in:bool = false


'''
淡入事件信号
'''
signal fade_in_event

'''
淡出事件信号
'''
signal fade_out_event


'''
初始化
'''
func _ready():
	if is_hidden:
		print_debug("hidden")
		hide()
	else:
		print_debug("display")
		show()
	set_process(false)


''''
调用淡入
'''
func fade_in():
	color.a = 1
	show()
	_use_fade_in = true
	_running = true
	set_process(true)
	print_debug("fade_in",self)
	pass

'''
调用淡出
'''
func fade_out():
	color.a = 0
	show()
	_use_fade_in = false
	_running = true
	set_process(true)
	print_debug("fade_out",self)
	pass


'''
调用过程
'''
func _process(delta):
	var a:float = delta * speed
	if _use_fade_in:
		color.a = color.a - a
		if color.a < 0:
			color.a = 0
			_running = false
			hide()
			fade_in_event.emit()
	else:
		color.a = color.a + a
		if color.a > 1:
			color.a = 1
			_running = false
			show()
			fade_out_event.emit()
		
	if not _running:
		set_process(false)
		print_debug("fade stop")

直接挂载在 ColorRect 对象就能启动简单渐变转场.