概要
スマート オブジェクト は、AI エージェントやプレイヤーがインタラクトできる、レベル内に配置されたオブジェクトです。これらのオブジェクトには、インタラクトに必要なすべての情報が含まれています。
スマート オブジェクトはグローバル データベースの一部であり、空間パーティショニング構造を使用します。したがって、ランタイム時に、位置、エージェントの近接度、タグなどのフィルタを使用してスマート オブジェクトをクエリできます。
大まかに言うと、スマート オブジェクトは、予約システムを通じて使用できる、レベル内の一連のアクティビティです。 留意点として重要なのは、スマート オブジェクトは実行ロジックを含まないことです。その代わり、スマート オブジェクトは、実装に応じて、インタラクターがインタラクトを行うために必要な情報すべてを提供します。各インタラクター (エージェントまたはプレイヤー) は、スマート オブジェクトに関する独自の実装ロジックを実行します。
スマート オブジェクトの要素
SmartObject サブシステム
SmartObject サブシステム は、レベル内で使用できるすべてのスマート オブジェクトを追跡する役割を持ちます。これは、スマート オブジェクト コンポーネントとコレクションとの間のリンクです。このサブシステムは、スマート オブジェクト プラグインがアクティブな場合に自動的にレベル内に作成されます。スマート オブジェクトのコレクションがない場合には、コレクションを作成します。
SmartObject コレクション
SmartObject コレクション は、レベルに関連付けられているすべての SmartObject コンポーネントのリストを含みます。このコレクションは、すべての共有コンフィギュレーションを保持しており、ロードされた領域外で大規模なワールドシミュレーションを効率的に行うために、スマート オブジェクトのすべてのランタイム インスタンスを作成するのに使用されます。
1 レベルにつき、SmartObject コレクションは 1 つだけです。
SmartObject コンポーネント
SmartObject コンポーネント は、任意の アクタ に追加して、レベル内でそのアクタをスマート オブジェクトに変換できます。このコンポーネントは、所定のスマート オブジェクト テンプレートのコンフィギュレーションを設定し、保存します。
SmartObject コンポーネントを含んでいるアクタは、ランタイム時に World Partition または ストリーミング を使用してロードおよびアンロードできます。SmartObject コンポーネントが永続的なワールドの一部の場合、ランタイム インスタンスはメモリ内でアクティブなまま残り、シミュレーションの一環として考慮されます。SmartObject コンポーネントを含んでいるアクタがランタイム時にスポーンする場合、そのアクタがアンロードされたら、そのアクタはメモリ内にアクティブなまま残ることはありません。
スマート オブジェクト定義
スマート オブジェクト定義 は、SmartObject のランタイム インスタンスの合計数の複数インスタンス間で共有される変更不可のデータです。スマート オブジェクト定義は、ユーザー指定のタグ、説明タグ、インタラクト時に実行するデフォルトの一連の動作など、フィルタリング情報を保存します。
スマート オブジェクト定義は、特定のスマート オブジェクトに対してエージェントまたはプレイヤーが使用できる 1 つ以上のスロットを公開します。各スロットには、親アンカーを基準とする位置と回転 (エディタ配置からベイク) と、いくつかのオーバーライド可能なプロパティが含まれています。オーバーライド可能なプロパティのよくある例としては、ユーザー指定のタグや、スロットごとの固有の動作があります。
スマート オブジェクト動作定義
スマート オブジェクト動作定義 には、所定のインタラクションに対してエージェントまたはプレイヤーが必要とするデータが含まれます。よくある動作の一例としては、ゲームプレイ動作、プレイヤー動作、MassEntity 動作 があります。ゲームプレイ動作は、ブループリントで直接実装できます。
ランタイム フロー
このセクションでは、エージェントがレベル内のスマート オブジェクトとインタラクトする仕組みを説明します。
エージェント データ
スマート オブジェクトを検索するために、エージェントには 1 つ以上のユーザー タグとオブジェクト タグのリストが必要です。この情報は、条件に一致するレベル内のスマート オブジェクトを検索する際に使用されます。
スマート オブジェクト データ
スマート オブジェクトは、そのオブジェクトの説明に使用される 1 つ以上の オブジェクト タグ を含んでいます。また、ユーザー タグのリストと、タグ クエリも含んでいます。タグ クエリは、スマート オブジェクトの使用を要求しているユーザーがそのオブジェクトとのインタラクトを許可されているかどうかを判断するために使用される式です。
スマート オブジェクトには Behavior クラス が設定されています。このクラスは、ユーザーがスマート オブジェクトとインタラクトしているときに使用される動作定義を含んでいます。
スマート オブジェクトを検索する
-
エージェントが、指定した間隔で近くのスマート オブジェクトを検索します。エージェントは、SmartObject サブシステムの FindSmartObjects メソッドを呼び出して検索を行います。このメソッドは、ユーザー タグ、オブジェクト タグ、Behavior クラス、検索領域を含んでいます。
-
SmartObject サブシステムが、検索領域内に含まれ、オブジェクト タグに一致するスマート オブジェクトすべてを検出します。
-
各スマート オブジェクトが、ユーザー タグを使用してタグ クエリを実行し、一致するものがあるかどうかを確認して、その結果を SmartObject サブシステムに送信します。
-
SmartObject サブシステムが、スマート オブジェクト結果をエージェントに返します。スマート オブジェクト結果は、条件に一致するスマート オブジェクトの ID すべてと、それらのスマート オブジェクトの空いているスロットを含んだ構造体配列です。
上記の画像のベンチはスマート オブジェクトです。2 つの空きスロットが灰色の輪で示されています。
スマート オブジェクトを要求する
-
エージェントが目的のスマート オブジェクト結果を選択し、SmartObject サブシステムの ClaimSmartObject メソッドを呼び出します。このメソッドは、スマート オブジェクトの使用可能なスロットの要求を試みます。
-
SmartObject サブシステムが、スマート オブジェクトの使用可能なスロットの要求を試みます。
-
スマート オブジェクトで使用可能なスロットが要求され、スロットの状態が Claimed に設定されます。確認が SmartObject サブシステムに送信されます。
-
SmartObject サブシステムが 要求ハンドル をエージェントに返します。
-
要求ハンドルが有効かどうかをエージェントが確認します。有効な場合、要求試行が成功し、次のステップに進むことができます。一方、要求ハンドルが無効の場合、エージェントは、スマート オブジェクト結果から別のスマート オブジェクトに要求を試みることができます。
要求されたスロットは、そのスロットを占有している現在のエージェントによってリリースされるまで、他のエージェントの要求を受けることはできません。
上記の画像では、エージェントが要求されたスロットに向かって移動し、ベンチ スマート オブジェクトに近づいています。
スマート オブジェクトに近づく
-
エージェントが SmartObject サブシステムの GetSlotLocation または GetSlotTransform メソッドを呼び出し、要求ハンドルを渡します。このメソッドは、要求されたスロットの位置またはトランスフォームを返します。
-
SmartObject サブシステムが、要求されたスロットの位置またはトランスフォームをエージェントに返します。
-
これで、エージェントがレベル内のスロットの位置に向かって移動を開始できます。エージェントは、目的地に到達するために、任意の移動方法を使用できます。
-
エージェントは、スロットの位置に到着すると、SmartObject サブシステムの UseSlot メソッドを呼び出して、要求ハンドルを渡します。
-
SmartObject サブシステムは、エージェントに 動作定義 構造体を返します。動作定義には、エージェントがスロットの位置で目的の動作を行うために必要なすべてのデータが含まれています。
-
UseSlot メソッドが、要求されたスロットの状態変化をトリガーします。スロットの状態が Claimed から Occupied に変化します。
上記の画像では、エージェントはスロットに到着すると目的の動作を開始します。スロットは Occupied 状態になり、赤の輪で示されます。
スマート オブジェクトをリリースする
-
エージェントが、動作定義に記述されている目的の動作を実行します。
-
その動作が完了するか失敗すると、エージェントが SmartObject サブシステムの ReleaseSmartObject メソッドを、要求ハンドルを指定して呼び出します。
-
SmartObject サブシステムによって、スロットの状態が Occupied から Free に変化します。
-
これで、エージェントは自由に別の動作を実行したり、別のスマート オブジェクトを検索したりできるようになります。
エージェントは、要求したスロットをリリースする必要があります。動作が完了するか、中断されると、リリースが発生します。
プロセスを中断する
上記で説明したプロセスは、エージェントまたはスマート オブジェクトで任意のタイミングで中断 (アボート) できます。
スマート オブジェクトの状態が変化した場合、Claimed または Occupied 状態のスロットすべてが自動的にリリースされ、OnSlotInvalidatedDelegate コールバックを通じて対応するエージェントに通知されます。一般的な例は、ゲームプレイ中にスマート オブジェクトが破棄される場合です。
また、エージェントは、理由を問わず任意のタイミングでプロセスを中断できます。このシナリオでは、エージェントは、他のエージェントが要求できるようにスロットをリリースする責任を持ちます。一般的な例は、エージェントが死んだり、優先度の高い他のタスクを実行したりする場合です。