スマート オブジェクトの概要

スマート オブジェクトは、予約システムを通じて使用できる、レベル内の一連のアクティビティです。

概要

スマート オブジェクト は、AI エージェントやプレイヤーがインタラクトできる、レベル内に配置されたオブジェクトです。これらのオブジェクトには、インタラクトに必要なすべての情報が含まれています。

スマート オブジェクトはグローバル データベースの一部であり、空間パーティショニング構造を使用します。そのため、ランタイム時に、位置、エージェントの近接度、タグなどのフィルタを使用してクエリできます。

大まかに言うと、スマート オブジェクトは、予約システムを通じて使用できる、レベル内の一連のアクティビティです。 重要なのは、スマート オブジェクトには実行ロジックが含まれていないということです。その代わりに、スマート オブジェクトは、実装に応じてインタラクターがインタラクトを行うのに必要な情報のすべてを提供します。各インタラクター (エージェントまたはプレイヤー) は、スマート オブジェクトに関する独自の実装ロジックを実行します。

スマート オブジェクトの要素

SmartObject サブシステム

SmartObject サブシステム は、レベル内で使用できるすべてのスマート オブジェクトを追跡する役割を持ちます。これは、スマート オブジェクト コンポーネントとコレクション間のリンクです。このサブシステムは、スマート オブジェクト プラグインがアクティブな場合に自動的にレベル内に作成され、スマート オブジェクトのコレクションがない場合はコレクションを作成します。

SmartObject コレクション

SmartObject コレクション には、レベルに関連付けられているすべての SmartObject コンポーネントのリストが含まれています。コレクションはパーシスタント レベルで機能し、ユーザーが手動でビルドする必要があります。

そのため、コレクションに登録されているスマート オブジェクトは、スマート オブジェクトのコンポーネントがパーシスタント レベルからロードされるのかアンロードされるのかにかかわらず維持されます。

各レベルの SmartObject コレクションは 1 つだけです。

SmartObject コンポーネント

SmartObject コンポーネント は、任意の アクタ に追加し、レベル内でそのアクタをスマート オブジェクトとしてマークできます。このコンポーネントは、所定のスマート オブジェクト テンプレートのコンフィギュレーションを格納する、スマート オブジェクト定義アセットをポイントします。

SmartObject コンポーネントを含むアクタは、ランタイム時に ストリーミング を使用してロードおよびアンロードできます。SmartObject コンポーネントが永続的なワールドの SmartObject コレクションに含まれている場合、ランタイム インスタンスはメモリ内でアクティブなままとなり、シミュレーションの一部とみなされます。SmartObject コンポーネントを含むアクタがランタイム時にスポーンされる場合、そのアクタはアンロードされるとメモリでアクティブなままにはなりません。

スマート オブジェクト定義

スマート オブジェクト定義 は、複数のスマート オブジェクトのランタイム インスタンス間で共有される不変のデータを含むデータ アセットです。スマート オブジェクト定義は、ユーザーに必須のタグ、アクティビティ タグ、オブジェクト アクティベーション タグ、スマート オブジェクトとのインタラクトで使用されることがあるデフォルトの一連の動作定義をはじめとする、フィルタリング情報を格納します。

スマート オブジェクト定義は、特定のスマート オブジェクトに対してエージェントまたはプレイヤーが使用できる 1 つ以上のスロットを公開します。各スロットには、(エディタ配置からベイクされる) 親アンカーを基準とする位置と回転、およびいくつかのオーバーライド可能なプロパティが含まれています。オーバーライド可能なプロパティの一般的な例としては、ユーザーに必須のタグやスロットごとの特定の動作定義などがあります。

スマート オブジェクト動作定義

スマート オブジェクト動作定義 には、所定のインタラクションに対してエージェントまたはプレイヤーが必要とするデータが含まれます。現在使用可能な動作定義には、次のような種類があります。

  • Mass Entity 動作 - Mass Entity で使用できるスマート オブジェクトの設定に使用するデータが含まれます。

  • ゲームプレイ動作 - Gameplay Behavior プラグインで使用できるスマート オブジェクトの設定に使用するデータが含まれます。

ランタイム フロー

このセクションでは、エージェントがレベル内のスマート オブジェクトとどのようにインタラクトするのかを学習します。

エージェント データ

スマート オブジェクトを検索するために、エージェントは 1 つ以上のゲームプレイ タグを使用できます。また、オブジェクトの目的のタグを含むタグ クエリ (アクティビティの要件) も使用することが可能です。この情報は、条件に一致するレベル内のスマート オブジェクトを検索する際に使用されます。

スマート オブジェクト データ

スマート オブジェクト定義には、オブジェクトの説明に使用される 1 つ以上のアクティビティ タグを含めることができます。また、タグ クエリと目的のタグのリストを含めることも可能です。タグ クエリは、スマート オブジェクトの使用を要求しているユーザーがそのオブジェクトとのインタラクトを許可されているかどうかを判断するために使用される式です。

スマート オブジェクト定義には、すべてのスロットで使用されるデフォルト動作定義のリストが含まれています。スロットに特定の動作定義が割り当てられている場合、特定の動作によってデフォルトの動作がオーバーライドされます。

スマート オブジェクトを検索する

  1. エージェントが、指定した間隔で近くのスマート オブジェクトを検索します。エージェントは、SmartObject サブシステムの FindSmartObjects メソッドを呼び出して検索を行います。このメソッドには、ユーザー タグ、アクティビティ タグ、動作定義クラス、検索領域が含まれています。

  2. SmartObject サブシステムが、指定されたすべてのフィルタに一致する、検索領域内のすべてのスマート オブジェクトを検出します。

  3. SmartObject サブシステムが、スマート オブジェクト結果をエージェントに返します。スマート オブジェクト結果は、条件に一致するスマート オブジェクトのすべてのハンドルとそれらの空きスロットを含む構造体の配列です。

    Smart Object with two free Slots

    「上記の画像は、緑色の輪で示された 1 つの空きロットがある乗り物のスマート オブジェクトです。」

スマート オブジェクトを要求する

  1. エージェントが目的のスマート オブジェクト結果を選択し、SmartObject サブシステムの ClaimSmartObject メソッドを呼び出します。このメソッドは、スマート オブジェクトのスロットの要求を試みます。

  2. SmartObject サブシステムが、スマート オブジェクトのスロットの要求を試みます。

  3. スマート オブジェクトで使用可能なスロットが要求され、スロットの状態が Claimed (要求中) に設定されます。

  4. SmartObject サブシステムが 要求ハンドル をエージェントに返します。

  5. 要求ハンドルが有効かどうかをエージェントが確認します。有効な場合は要求の試行が成功し、次の手順に進むことができます。一方、要求ハンドルが無効の場合、エージェントはスマート オブジェクト結果から別のスマート オブジェクト スロットへの要求を試みることができます。

    要求中のスロットは、それを要求したエージェントによってリリースされるまで、他のエージェントの要求を受けることはできません。

    Smart Object with two claimed Slots

    上記の画像では、エージェントによってスロット 0 が要求されています。

スマート オブジェクトに近づく

  1. エージェントが SmartObject サブシステムの GetSlotLocation または GetSlotTransform メソッドを呼び出し、要求ハンドルを渡します。このメソッドは、要求されたスロットの位置またはトランスフォームを返します。

    ユーザーは、次の C++ コードを使用してスロットのトランスフォームを取得することもできます。

        FSmartObjectSlotView:
        FSmartObjectSlotView View = Subsystem->GetSlotView(ClaimHandle.SlotHandle);
    
        const FSmartObjectSlotTransform& SlotTransform = View.GetStateData<FSmartObjectSlotTransform>();
        FTransform Transform = SlotTransform.GetTransform();
  2. SmartObject サブシステムが、要求されたスロットの位置またはトランスフォームをエージェントに返します。

  3. これで、エージェントがレベル内のスロットの位置に向かって移動を開始できるようになります。エージェントは、目的地に到達するために任意の移動方法を使用できます。

  4. エージェントがスロットの位置に到着し、SmartObject サブシステムの Use メソッドを呼び出して要求ハンドルを渡します。

  5. Use メソッドが、要求されたスロットの状態変化をトリガーします。スロットの状態が Claimed から Occupied (占有中) に変化します。

  6. SmartObject サブシステムが、エージェントに 動作定義 構造体を返します。動作定義には、エージェントがスロットの位置で目的の動作を行うために必要なすべてのデータが含まれています。

    Smart Object with an Occupied Slot and a Claimed Slot

    上記の画像では、エージェントはスロットに到着すると目的の動作を開始します。スロットは Occupied 状態になり、赤色の輪で示されます。

スマート オブジェクトをリリースする

  1. エージェントが、動作定義に記述されている目的の動作を実行します。

  2. その動作が完了するか中断されると、エージェントが SmartObject サブシステムの要求ハンドルで Release メソッドを呼び出します。

  3. SmartObject サブシステムが、スロットの状態を Occupied から Free (空き) に変更します。

  4. これで、エージェントは自由に別のタスクを実行したり、別のスマート オブジェクトを検索したりできるようになります。

    エージェントは、要求したスロットをリリースする責任を負います。リリースは、動作が完了するか中断されると行われます。

プロセスを中断する

上記で説明したプロセスは、エージェントまたはスマート オブジェクトで任意のタイミングで中断 (アボート) できます。

スマート オブジェクトの状態が変化した場合、Claimed または Occupied 状態のスロットのすべてが自動的にリリースされ、OnSlotInvalidatedDelegate コールバックを通じて対応するエージェントに通知されます。一般的な例としては、ゲームプレイ中に破壊されるスマート オブジェクトがあります。

またエージェントは、理由を問わず任意のタイミングでプロセスを中断できます。このシナリオでは、エージェントは、他のエージェントが要求できるようにスロットをリリースする責任を負います。一般的な例としては、エージェントが死んだり、優先度の高い他のタスクを実行したりといったことが挙げられます。

タグ
Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
キャンセル