如何在不破坏(释放)我要离开的场景的情况下切换场景?
How can I switch between scenes without destroying (freeing) the scene I'm leaving?
嘿,我的游戏里有战斗。目前,战斗是一个单独的场景,当玩家走向 NPC 时,我们有一点过渡,然后离开场景,我们进入战斗场景。一旦战斗场景完成,我想 return 到我们之前的场景,一切都完全一样。我目前有一个名为 scene_switcher 的场景切换单例,当前设置为
extends Node
var _params = null
func change_scene(next_scene, params = null):
_params = params
# global_data is another singleton I use for storing state and other global data
global_data.previous_scene = get_tree().get_current_scene()
get_tree().change_scene(next_scene)
func return_to_previous_scene(params = null):
_params = params
get_tree().get_current_scene().free()
get_tree().get_root().add_child(global_data.previous_scene)
get_tree().set_current_scene(global_data.previous_scene)
func get_param(name):
if _params != null and _params.has(name):
return _params[name]
return null
当我们进入战斗时,我使用
scene_switcher.change_scene("res://battlescene.tcsn", {players_deck, opponents_deck})
原样存储当前场景,并将玩家数据传递给战斗场景。
一旦战斗结束,我会调用 return_to_previous_scene()
,当满足其中一个胜利条件时,我会调用
scene_switcher.return_to_previous_scene()
但是我得到了错误:
Attempted to free a locked object (calling or emitting).
我已经尝试根据此代码将调用推迟到空闲时间 on the singleton autoload page of the docs 但是当我这样做时:
call_deferred("scene_switcher.return_to_previous_scene")
它永远不会被调用(game_over 函数工作,它打印出结果,我的其他测试让它与下面的代码一起工作,我认为场景永远不会空闲,这意味着代码永远不会有机会开火)
现在我可以使用:
scene_switcher.change_scene("res://map.tcsn", {})
但这会将场景恢复到原始状态并且可扩展性不强(如果我可以在 12 个不同级别与人战斗,我怎么知道要加载哪个场景?)
那么如何停止当前场景。离开,然后return 带着我前一幕的一切离开怎么办呢?谢谢:)
我问这个same question on reddit and got an answer that solved my problem. Copying over here for anyone who might find this question in the future. All credit to /u/thomastc
call_deferred takes a method name only, so:
scene_switcher.call_deferred("return_to_previous_scene")
Alternatively, just use queue_free instead of free, to defer only the freeing.
我没有正确使用 call_deferred。
我还对 change_scene
中的场景使用 duplicate()
进行了细微修改,以保留未释放的副本。
所以
global_data.previous_scene = get_tree().get_current_scene()
变成了
global_data.previous_scene = get_tree().get_current_scene().duplicate()
现在可以正常工作了:)
嘿,我的游戏里有战斗。目前,战斗是一个单独的场景,当玩家走向 NPC 时,我们有一点过渡,然后离开场景,我们进入战斗场景。一旦战斗场景完成,我想 return 到我们之前的场景,一切都完全一样。我目前有一个名为 scene_switcher 的场景切换单例,当前设置为
extends Node
var _params = null
func change_scene(next_scene, params = null):
_params = params
# global_data is another singleton I use for storing state and other global data
global_data.previous_scene = get_tree().get_current_scene()
get_tree().change_scene(next_scene)
func return_to_previous_scene(params = null):
_params = params
get_tree().get_current_scene().free()
get_tree().get_root().add_child(global_data.previous_scene)
get_tree().set_current_scene(global_data.previous_scene)
func get_param(name):
if _params != null and _params.has(name):
return _params[name]
return null
当我们进入战斗时,我使用
scene_switcher.change_scene("res://battlescene.tcsn", {players_deck, opponents_deck})
原样存储当前场景,并将玩家数据传递给战斗场景。
一旦战斗结束,我会调用 return_to_previous_scene()
,当满足其中一个胜利条件时,我会调用
scene_switcher.return_to_previous_scene()
但是我得到了错误:
Attempted to free a locked object (calling or emitting).
我已经尝试根据此代码将调用推迟到空闲时间 on the singleton autoload page of the docs 但是当我这样做时:
call_deferred("scene_switcher.return_to_previous_scene")
它永远不会被调用(game_over 函数工作,它打印出结果,我的其他测试让它与下面的代码一起工作,我认为场景永远不会空闲,这意味着代码永远不会有机会开火)
现在我可以使用:
scene_switcher.change_scene("res://map.tcsn", {})
但这会将场景恢复到原始状态并且可扩展性不强(如果我可以在 12 个不同级别与人战斗,我怎么知道要加载哪个场景?)
那么如何停止当前场景。离开,然后return 带着我前一幕的一切离开怎么办呢?谢谢:)
我问这个same question on reddit and got an answer that solved my problem. Copying over here for anyone who might find this question in the future. All credit to /u/thomastc
call_deferred takes a method name only, so:
scene_switcher.call_deferred("return_to_previous_scene")
Alternatively, just use queue_free instead of free, to defer only the freeing.
我没有正确使用 call_deferred。
我还对 change_scene
中的场景使用 duplicate()
进行了细微修改,以保留未释放的副本。
所以
global_data.previous_scene = get_tree().get_current_scene()
变成了
global_data.previous_scene = get_tree().get_current_scene().duplicate()
现在可以正常工作了:)