手动更改场景
Viewport 的子节点将呈现给它生成的图像. 即使对于 “当前” 场景之外的节点, 这也适用. Autoloads属于这一类, 但是一个实例在运行时添加到树中的场景也是如此: GDScript C#
var simultaneous_scene = preload("res://levels/level2.tscn").instance()func _add_a_scene_manually(): # This is like autoloading the scene, only # it happens after already loading the main scene. get_tree().get_root().add_child(simultaneous_scene)
public PackedScene simultaneousScene;public MyClass(){ simultaneousScene = (PackedScene)ResourceLoader.Load("res://levels/level2.tscn").instance();}public void _AddASceneManually(){ // This is like autoloading the scene, only // it happens after already loading the main scene. GetTree().GetRoot().AddChild(simultaneousScene);}
Viewport. 权衡涉及平衡操作速度和内存消耗以及平衡数据访问和完整性.
- 我们可以删除现有场景. SceneTree.change_scene() 和 SceneTree.change_scene_to() 会立即删除当前场景. 不过开发者也可以删除主场景. 假设根节点的名字是 “Main”, 可以执行
get_node("/root/Main").free()来删除整个场景.- 卸载内存.
- 好处: RAM不再拖累自重.
- 坏处: 回到那个场景现在更加昂贵, 因为它必须再次加载回内存(需要时间和内存). 如果不久就回来是不必要的.
- 坏处: 无法再访问该场景的数据. 如果不久就使用这些数据就不成问题了.
- SceneTree, 可以将数据保存在即将删除的场景中.
- 处理停止.
- 好处: 没有节点意味着没有进程, 物理过程或输入处理. CPU可用于处理新场景的内容.
- 坏处: 这些节点的处理和输入处理不再运行. 如果不需要使用更新的数据, 则不成问题.
- 我们可以隐藏现有场景. 通过更改节点的可见性或碰撞检测, 我们可以从游戏角色的角度隐藏整个节点子树.
- 记忆仍然存在.
- 好处: 如果需要, 仍然可以访问数据.
- 好处: 无需再移动任何节点来保存数据.
- 坏处: 更多数据被保存在内存中, 这将成为对内存敏感平台(如Web或移动设备)的问题.
- 处理继续.
- 好处: 数据继续接收处理更新, 因此场景将不断更新其中依赖于增量时间或帧数据的任何数据.
- SceneTree).
- 坏处: 现在CPU的注意力分散在两个场景之间. 负载过大可能导致帧速率降低. 应该确保测试性能, 以确保目标平台能够支持它们提供的负载.
- 我们可以从树上删除现有的场景. 给现有场景的根节点分配一个变量. 然后使用 Node.remove_child(Node) 来将整个场景从树上分离.
- 记忆仍然存在(与从视图中隐藏它相似的优点/缺点).
- 处理停止(类似于完全删除它的优点/缺点).
- 亲: 这种 “隐藏” 的变化更容易显示/隐藏. 人们必须只调用一个方法add / remove_child方法, 而不是潜在地跟踪场景的多个变化. 它类似于在其他引擎中禁用游戏对象.
- SceneTree access的数据, 则它将变为陈旧.
在有些情况下, 人们可能希望有许多场景同时存在. 也许人们在运行时添加他们自己的单例, 或者在场景变化之间保留一个场景的数据(将场景添加到根节点).
GDScript
C#
get_tree().get_root().add_child(scene)
ViewportContainers 来同时显示多个场景。这意图是在屏幕的不同部分渲染不同内容的情况下是最理想的。迷你地图和多人分屏游戏就是很好的例子。 每个选项都有最合适的情况, 因此必须检查每个选项的效果并确定最适合其独特情况的路径.GetTree().GetRoot().AddChild(scene);
