Godot Custom scene switcher自定义场景切换器
本教程将演示使用自动加载功能构建场景切换器。 对于基本的场景切换,可以使用SceneTree.change_scene()方法(有关详细信息,请参见SceneTree)。 但是,如果在更改场景时需要更复杂的行为,则此方法可提供更多功能。
首先,请从此处下载模板:autoload.zip并在Godot中将其打开。
该项目包含两个场景:Scene1.tscn和Scene2.tscn。 每个场景都包含一个显示场景名称的标签和一个连接了其pressed()信号的按钮。 运行项目时,它从Scene1.tscn启动。 但是,按此按钮不起作用。
Global.gd
切换到“脚本”选项卡并创建一个名为Global.gd的新脚本。 确保它继承自Node:
下一步是将此脚本添加到autoLoad列表中。 从菜单中打开“项目”>“项目设置” ,切换到“自动加载”选项卡,然后通过单击浏览按钮或键入其路径来选择脚本:res://Global.gd。 按添加将其添加到自动加载列表中:
现在,无论何时在项目中运行任何场景,该脚本都将始终加载。
返回脚本,它需要在_ready()函数中获取当前场景。 当前场景(带有按钮的场景)和Global.gd都是root的子级,但是自动加载的节点始终是第一个。 这意味着root的最后一个孩子始终是加载的场景。
extends Node
var current_scene = null
func _ready():
var root = get_tree().get_root()
current_scene = root.get_child(root.get_child_count() - 1)
现在,我们需要一个用于更改场景的功能。 此功能需要释放当前场景并将其替换为请求的场景。
func goto_scene(path):
# This function will usually be called from a signal callback,
# or some other function in the current scene.
# Deleting the current scene at this point is
# a bad idea, because it may still be executing code.
# This will result in a crash or unexpected behavior.
# The solution is to defer the load to a later time, when
# we can be sure that no code from the current scene is running:
#这个函数通常会从一个信号回调、
#或当前场景中的其他函数中调用。此时删除当前场景不是一个好主意,
#因为它可能仍在执行代码。这将导致崩溃或意外行为。
#解决方案是将加载延迟到稍后的时间,此时我们可以确保当前场景中没有代码在运行
call_deferred("_deferred_goto_scene", path)
func _deferred_goto_scene(path):
# It is now safe to remove the current scene
#现在可以安全地移除当前场景了
current_scene.free()
# Load the new scene.
#加载新场景。
var s = ResourceLoader.load(path)
# Instance the new scene.
#实例化新场景。
current_scene = s.instance()
# Add it to the active scene, as child of root.
#将它添加到活动场景中,作为根的子级。
get_tree().get_root().add_child(current_scene)
# Optionally, to make it compatible with the SceneTree.change_scene() API.
#(可选)使其与SceneTree.change_scene()API兼容。
get_tree().set_current_scene(current_scene)
使用Object.call_deferred(),仅当当前场景中的所有代码完成后,第二个函数才会运行。 因此,当前场景仍在使用中(即其代码仍在运行)将不会被删除。
最后,我们需要在两个场景中填充空的回调函数:
#Add to 'Scene1.gd'.
func _on_Button_pressed():
Global.goto_scene("res://Scene2.tscn")
and
#Add to 'Scene2.gd'.
func _on_Button_pressed():
Global.goto_scene("res://Scene1.tscn")
运行该项目并测试您可以通过按下按钮在场景之间进行切换。
Note
当场景较小时,过渡是瞬时的。 但是,如果您的场景比较复杂,则可能需要花费相当长的时间才能显示出来。 要了解如何处理此问题,请参阅下一个教程:后台加载。或者,如果加载时间相对较短(少于3秒左右),则可以在更改场景之前通过显示某种2D元素来显示“加载信息”。 然后,可以在场景更改后立即将其隐藏。 这可以用于向播放器指示正在加载场景。