インスタンスの作成¶
前のパートでは、シーンとは1つのノードをルートとし、ツリー構造で構成されたノードの集まりであることを見てきました。プロジェクトは、いくつものシーンに分割することができます。この機能により、ゲームの様々なコンポーネントを分解して整理することができます。
好きなだけシーンを作成し、.tscn
("text scene") という拡張子でディスクに保存することが可能です。前のレッスンのLabel.tscn
ファイルはその例です。これらのファイルは、シーンの内容に関する情報をパックしているため、"Packed Scenes"と呼んでいます。
以下はボールの例です。ボールが落ちたり壁で跳ねたりできるようにするために、Ballという名前の RigidBody2D ノードをルートとしており、さらに Sprite ノードと CollisionShape2D から構成されています。
一度保存したシーンは設計図として機能し、他のシーンで何度でも再現することができます。このようにテンプレートからオブジェクトを複製することを、instancing と呼びます。
前のパートで述べたように、インスタンス化されたシーンは、ノードのように動作します。エディタは、デフォルトでそのコンテンツを隠蔽します。Ballをインスタンス化すると、Ballノードだけが表示されます。また、各複製がユニークな名前を持っていることに注意してください。
Ball シーンのすべてのインスタンスは、Ball.tscn
と同じ構造とプロパティで開始されます。ただし、それぞれを独立して変更することができます。たとえば、跳ね返り方、重さ、またはソース シーンによって公開されるプロパティを変更することができます。
実際に使う¶
インスタンス化を実際に使って、Godotで具体的にどう動くのかを見てみましょう。私たちが用意したボールのサンプルプロジェクトをダウンロードしてください: instancing.zip
.
このプロジェクトを任意の場所で解凍してください。次に、Godotを開き、[インポート]ボタンを使用してこのプロジェクトをプロジェクトマネージャーに追加してください。
表示されたポップアップで、参照ボタン("Browse")をクリックし、解凍したフォルダに移動します。
project.godot
ファイルをダブルクリックして開いてください。
最後に、「インポートと編集」("Import & Edit")ボタンをクリックします。
このプロジェクトには、2つのパックされたシーンが含まれています。Main.tscn
(ボールと衝突する壁を含む)とBall.tscn
のシーンです。メインシーンは自動的に開きます。
Mainノードの子として、ボールを追加してみましょう。Scene ドックで、Main ノードを選択します。次に、シーンドックの上部にあるリンクアイコンをクリックします。このボタンで、現在選択されているノードの子として、シーンのインスタンスを追加することができます。
Ballシーンをダブルクリックしてインスタンス化します。
ビューポートの左上隅にボールが表示されます。
それをクリックし、ビューの中心に向かってドラッグします。
F5キーを押してゲームを実行してください。ボールが落ちるのが見えるはずです。
さて、Ball ノードのインスタンスをさらに作成したいと思います。ボールを選択したまま、 Ctrl-D (macOS では Cmd-D) を押して、複製コマンドを呼び出します。クリックアンドドラッグして、新しいボールを別の場所に移動します。
この作業を、シーン内にいくつかボールができるまで繰り返すことができます。
もう一度ゲームを実行します。今度は、すべてのボールが互いに独立して落下するのが見えるはずです。これがインスタンスの役割です。それぞれが、テンプレートのシーンを独立して再現しているのです。
シーンとインスタンスの編集¶
インスタンスにはまだまだあります。この機能を使用すると、次のことができます。
インスペクタを使って、1つのボールのプロパティを他のボールに影響を与えずに変更します。
Ball.tscn
シーンを開き、Ball ノードに変更を加えることによって、すべての Ball のデフォルトプロパティを変更することができます。保存すると、プロジェクト内のすべてのBallインスタンスの値が更新されます。
注釈
インスタンスのプロパティを変更すると、対応するパックされたシーンの値が常に上書きされます。
試してみましょう。Ball.tscn
を開き、Ball ノードを選択します。右側のインスペクタで、PhysicsMaterialプロパティをクリックして展開します。
数値フィールドをクリックし、2
と入力し、 Enter を押して、バウンスプロパティを 2
にセットしてください。
kbd:F5 を押してゲームを実行して、すべてのボールがより多くバウンドすることに注目してください。ボールのシーンはすべてのインスタンスのテンプレートなので、これを修正して保存すると、すべてのインスタンスがそれに応じて更新されます。
それでは、個々のインスタンスを調整しましょう。ビューポートの上にある対応するタブをクリックして、Mainシーンに戻りましょう。
インスタンス化されたBallノードの1つを選択し、インスペクタで、その重力スケール("Gravity Scale")値を10
に設定します。
変更したプロパティの横に、グレーの「復元」ボタンが表示されます。
このアイコンは、元のパックされたシーンから値を上書きしていることを示します。元のシーンでプロパティを変更しても、値のオーバーライドはインスタンスに保存されます。復元アイコンをクリックすると、プロパティが保存されたシーンの値に復元されます。
ゲームを再実行し、このボールが他のボールよりずっと速く落ちていることに注目してください。
注釈
あるインスタンスのPhysicsMaterial
の値を変更すると、他のすべてのインスタンスに影響を及ぼします。これは、PhysicsMaterial
がリソースであり、リソースはインスタンス間で共有されるからです。リソースを1つのインスタンスに固有にするには、インスペクタでそのリソースを右クリックし、コンテキストメニューの「ユニーク化」をクリックします。
リソースは、後のレッスンで取り上げますが、Godotゲームの重要な構成要素の一つです。
デザイン言語としてのシーンインスタンス¶
Godotのインスタンスとシーンは、優れたデザイン言語を提供し、他のエンジンとは一線を画しています。私たちは、一からこのコンセプトに基づいてGodotを設計しました。
Godot でゲームを作る場合、MVC (Model-View-Controller) や Entity-Relationship ダイアグラムのようなアーキテクチャのコードパターンを排除することをお勧めします。その代わりに、プレイヤーがゲームの中で目にする要素を想像することから始め、それらに基づいてコードを構成するとよいでしょう。
例えば、シューティングゲームを分解すると、こんな感じです。
このような図は、ほとんどどんな種類のゲームでも思いつくでしょう。それぞれの長方形は、プレイヤーの視点からゲーム内で見えるエンティティを表しています。矢印は、どのシーンがどれを所有しているかを示しています。
ダイアグラムができたら、そこに記載されている各要素のシーンを作成して、ゲームを開発することをお勧めします。シーンのツリーを構築するために、コードまたはエディタで直接インスタンス化を使用します。
プログラマーは、抽象的なアーキテクチャを設計し、そこにコンポーネントを当てはめようとすることに多くの時間を費やす傾向があります。シーンをベースにした設計は、開発をより速く、より簡単にし、ゲームロジックそのものに集中することができます。ほとんどのゲームコンポーネントはシーンに直接マッピングされるため、シーンのインスタンス化をベースにしたデザインを使用すると、他のアーキテクチャのコードはほとんど必要ありません。
ここでは、大量のアセットとネストされた要素を持つオープンワールドゲームのシーン図の例を示します。
まず、部屋を作るところから始めると想像してください。家具をユニークに配置した、いくつかの異なる部屋のシーンを作成することができます。その後、インテリアに複数の部屋のインスタンスを使用する家のシーンを作成することができます。インスタンス化された多くの家と、城塞を置くための大きな地形から、城塞を作ることになります。これらは、それぞれ1つまたは複数のサブシーンをインスタンス化したシーンとなります。
その後、衛兵のシーンを作り、城塞に追加することもできます。間接的にゲームの世界全体に追加されることになります。
Godotでは、このようにシーンを作成してインスタンス化するだけで、簡単にゲーム上で反復することができます。エディターは、プログラマー、デザイナー、アーティストが同様に利用できるように設計されています。典型的なチーム開発では、2Dや3Dのアーティスト、レベルデザイナー、ゲームデザイナー、アニメーターが参加し、全員がGodotエディターで作業を行います。
概要¶
インスタンス化とは、設計図からオブジェクトを生成するプロセスで、多くの便利な使い方があります。シーンを使えば、次のようなことが得られます。
ゲームを再利用可能なコンポーネントに分割する機能。
複雑なシステムを構造化し、カプセル化するためのツール。
ゲームプロジェクトの構造を自然な方法で考えるための言語。