シーンを手動で変更する

シーンを入れ替える方法をより詳細に制御できると便利な場合があります。前述のように、Viewport の子ノードは、生成する画像にレンダリングします。これは、「現在の」シーン外のノードにも当てはまります。自動ロードはこのカテゴリに分類されますが、実行時にツリーにインスタンスを追加するシーンも同様です:

var simultaneous_scene = preload("res://levels/level2.tscn")

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");
}

public void _AddASceneManually()
{
    // This is like autoloading the scene, only
    // it happens after already loading the main scene.
    GetTree().GetRoot().AddChild(simultaneousScene);
}

サイクルを完了し、古いシーンと新しいシーンを交換するとき、開発者には複数の選択肢があります。Viewport のビューからシーンを削除する方法は数多く存在します。トレードオフには、操作速度とメモリ消費のバランスをとることと、データアクセスと整合性のバランスを取る必要があります。

  1. 既存のシーンを削除できます。 SceneTree.change_scene() および SceneTree.change_scene_to() は現在のシーンをすぐに削除します。ただし、開発者はメインシーンを削除することもできます。ルートノードの名前が "Main" だとすると、get_node("/root/Main").free() を実行してシーン全体を削除できます。

    • メモリをアンロードします。

      • 長所: RAMはもはやデッドウェイトを引きずっていません。
      • 短所: 再びメモリにロードし直す必要があるため、そのシーンに戻るのにコストがかかります(時間がかかります)。すぐに戻る必要がない場合は問題ありません。
      • 短所: そのシーンのデータにアクセスできなくなります。そのデータをすぐに使用する必要がない場合は問題ありません。
      • 注: 1つまたは複数のノードを別のシーンに再アタッチするか、SceneTree に直接アタッチすることで、間もなく削除されるシーンのデータを保存すると便利です。
    • 処理の停止。

      • 長所: ノードがないということは、プロセス、物理プロセス、または入力処理がないことを意味します。 CPUは、新しいシーンのコンテンツを処理するために使用できます。
      • 短所: これらのノードの処理と入力処理は動作しなくなります。更新されたデータを使用する必要がない場合は問題ありません。
  2. 既存のシーンを非表示にできます。 ノードの可視性または衝突検出を変更することにより、プレイヤーの視点からノードサブツリー全体を隠すことができます。

    • メモリはまだ存在しています。

      • 長所: 必要に応じてデータにアクセスできます。
      • 長所: データを保存するためにノードを移動する必要はありません。
      • 短所: より多くのデータがメモリに保持されているため、Webやモバイルなどのメモリに敏感なプラットフォームで問題になります。
    • 処理は続行されます。

      • 長所: データは処理の更新を引き続き受信するため、シーンは、デルタ時間またはフレームデータに依存するデータを更新し続けます。
      • 長所: ノードはまだグループのメンバーです(グループは SceneTree に属しているため)。
      • 短所: CPUの負担は両方のシーンに分かれています。負荷が多すぎると、フレームレートが低下する可能性があります。ターゲットプラットフォームが提供する負荷をサポートできることを確認するために、パフォーマンスをテストする必要があります。
  3. 既存のシーンをツリーから削除できます。 変数を既存のシーンのルートノードに割り当てます。次に Node.remove_child(Node) を使用して、シーン全体をツリーからデタッチします。

    • メモリはまだ存在します(ビューから隠す場合と同様の長所と短所)。
    • 処理は停止します(完全に削除する場合と同様の長所と短所)。
    • 長所: この「非表示」のバリエーションは、表示/非表示がはるかに簡単です。シーンに対する複数の変更を追跡するのではなく、1つの add/remove_child のメソッドペアのみを呼び出す必要があります。他のエンジンでゲームオブジェクトを無効にする方法と似ています。
    • 短所: 表示のみから非表示にする場合とは異なり、デルタ時間、入力、グループ、または SceneTree アクセスから派生した他のデータに依存している場合、シーン内に含まれるデータは、古いままになってしまいます。

多くのシーンを同時に表示したい場合もあります。おそらく、実行時に独自のシングルトンを追加するか、シーンの変更間でシーンのデータを保持する(シーンをルートノードに追加する)のでしょう。

get_tree().get_root().add_child(scene)
GetTree().GetRoot().AddChild(scene);

代わりに、ViewportContainers を使用して、複数のシーンを同時に表示したい場合があります。これは、画面のさまざまな部分にさまざまなコンテンツを表示することが目的の場合に最適です。ミニマップと分割画面マルチプレイヤーが良い例です。

各オプションには最適なケースがあるため、それぞれの効果を調べて、それぞれの状況に最適なパスを決定する必要があります。