UE Blueprintで作る○○なゲーム

UE Blueprintで作る汎用的なオブジェクトインタラクションシステム

Tags: Blueprint, インタラクション, インターフェース, ゲームシステム, チュートリアル

はじめに

Unreal Engine (UE) を用いたゲーム開発において、プレイヤーがゲーム世界のオブジェクトとどのように関わるかは、ゲームプレイの面白さを左右する重要な要素です。ドアを開ける、アイテムを拾う、スイッチを押すといった様々なインタラクションを、汎用性を持たせて効率的に実装することは、開発の生産性を高める上で非常に重要になります。

この記事では、Blueprintのみを使用して、プレイヤーキャラクターがゲーム内の様々なオブジェクトとインタラクションするための、拡張性の高い汎用システムを構築する方法をステップバイステップで解説します。特に、プログラミング経験のある読者の方々には馴染み深い「インターフェース」の概念をBlueprintでどのように活用するかを中心に据え、効率的かつ整理されたBlueprintの組み方を習得していただくことを目指します。

1. インタラクションシステムの基本設計とインターフェースの導入

汎用的なインタラクションシステムを構築する上で最も重要なのが、「どのようなオブジェクトでもインタラクション可能にするための共通の接点」を用意することです。これはプログラミングにおける「インターフェース」の概念に他なりません。Blueprintでは「Blueprint Interface」としてこの機能が提供されています。

1-1. Blueprint Interfaceの作成

まず、インタラクション可能なオブジェクトが共通して持つべき機能を定義するインターフェースを作成します。

  1. コンテンツブラウザ内で右クリックし、Blueprint -> Blueprint Interface を選択します。
  2. 名前を BPI_Interactable とします。
  3. BPI_Interactable をダブルクリックして開きます。
  4. 「関数」セクションで、デフォルトで作成されている NewFunction_0 の名前を Interact に変更します。
  5. Interact 関数を選択し、詳細パネルで必要に応じて引数を追加できます。例えば、Interactor (インタラクションを行ったActor、通常はプレイヤーキャラクター)として Object 型の引数を追加しておくと、後々の処理で便利です。
    • 引数名: Interactor
    • 型: Object Reference

1-2. インターフェースの役割とメリット

BPI_Interactable を作成することで、私たちは以下のメリットを享受できます。

2. インタラクト可能オブジェクトの実装

次に、作成した BPI_Interactable インターフェースを実際にActorに実装し、具体的なインタラクションロジックを記述します。ここでは例として「開閉するドア」を作成します。

2-1. ドア用Actorの作成

  1. コンテンツブラウザ内で右クリックし、Blueprint Class を選択します。
  2. Actor を親クラスとして選択し、名前を BP_Door とします。
  3. BP_Door をダブルクリックして開きます。
  4. Componentsパネルで Static Mesh コンポーネントを追加し、ドアのメッシュを設定します。

2-2. BPI_Interactable の実装と Interact イベントの処理

  1. BP_DoorClass Settings を開きます。
  2. 「Interfaces」セクションの「Implemented Interfaces」で Add ボタンをクリックし、BPI_Interactable を選択します。
  3. これにより、BPI_Interactable で定義した Interact 関数が BP_Door のEvent Graph内でイベントとして利用可能になります。
  4. Event Graphに戻り、右クリックして Event Interact と検索し、イベントノードを追加します。
  5. この Event Interact ノードからドアの開閉ロジックを実装します。ここでは簡略化のため、ドアの回転アニメーションを例とします。

    blueprint Event Interact (Interactor) ├── Branch (Is Door Open?) │ ├── True (ドアが開いている場合) │ │ └── Timeline (ドアを閉じるアニメーション) │ │ └── Update -> Set Relative Rotation (Static Mesh Component) │ └── False (ドアが閉じている場合) │ └── Timeline (ドアを開くアニメーション) │ └── Update -> Set Relative Rotation (Static Mesh Component) * Timelineの作成: Event Graph内で右クリックし、Add Timeline を選択します。タイムラインエディタを開き、Vector Track を追加してドアの回転値(YawまたはZ軸の回転)を時間経過で変化させます。例えば、0秒で0度、1秒で90度になるようにカーブを設定します。 * Set Relative Rotation: TimelineのUpdateピンからSet Relative Rotationノードを接続し、対象をドアのStatic Mesh Componentに設定します。回転値はTimelineのVector Trackから取得します。 * 状態管理: bIsOpen といったBoolean変数を作成し、ドアの開閉状態を管理します。Event Interact が呼ばれるたびにこの変数をトグルし、Timelineの再生方向 (Play または Reverse) を切り替えます。

3. プレイヤーキャラクターからのインタラクション実行

プレイヤーキャラクターがゲーム世界でインタラクト可能オブジェクトを検出し、そのオブジェクトに対して Interact 関数を呼び出すロジックを実装します。

3-1. プレイヤー入力とLine Trace

ここでは、キーボードの E キーを押した際にプレイヤーの視線の先にインタラクト可能なオブジェクトがあるかを検出するロジックを BP_ThirdPersonCharacter (またはご自身のプレイヤーキャラクターBlueprint)に実装します。

  1. BP_ThirdPersonCharacter のEvent Graphを開きます。
  2. Input Action E イベントを追加します。
  3. Pressed ピンから Line Trace By Channel ノードを接続します。
    • Start: Get Actor Location (Self) に Get Forward Vector (Camera/FollowCamera) を乗算したものを加算し、カメラの少し前からスタートさせます。
    • End: Start 地点から Get Forward Vector (Camera/FollowCamera) をさらに乗算(距離分)したものを加算し、ある程度離れた位置を終点とします。(例: Start + ForwardVector * 500)
    • Trace Channel: Visibility など、適切なコリジョンチャンネルを選択します。
    • Draw Debug Type: For Duration に設定すると、デバッグ用の線が表示され、トレースの動作確認に役立ちます。

3-2. 検出したオブジェクトのチェックとインタラクションの実行

Line Trace By ChannelOut Hit から、検出したオブジェクトが BPI_Interactable インターフェースを実装しているかを確認します。

  1. Line Trace By ChannelOut Hit ピンから Break Hit Result を接続します。
  2. Break Hit ResultHit Actor ピンから Does Implement Interface ノードを接続します。
  3. Does Implement InterfaceInterfaceBPI_Interactable を設定します。
  4. Return ValueTrue の場合、つまりインタラクト可能なオブジェクトである場合にのみインタラクションを実行します。
  5. Does Implement InterfaceReturn ValueTrue であれば、Hit Actor ピンから Interact (Message) ノードを呼び出します。

    • Interact ノードは、インターフェースを実装しているActorに対して「メッセージ」を送信する形で関数を呼び出します。これがBlueprint Interfaceの仕組みです。
    • Interactor 引数には Self (プレイヤーキャラクター自身)を渡します。

    blueprint Input Action E (Pressed) ├── Line Trace By Channel (Start, End, Trace Channel=Visibility, Draw Debug Type=For Duration) │ ├── On Hit (True) │ │ └── Break Hit Result │ │ ├── Hit Actor │ │ │ └── Does Implement Interface (Interface=BPI_Interactable) │ │ │ └── Branch (True) │ │ │ └── Interact (Message) (Target=Hit Actor, Interactor=Self)

これで、プレイヤーが E キーを押すと、視線上のインタラクト可能なオブジェクト(この場合はドア)が開閉する基本的なシステムが完成しました。

4. 応用と発展

この汎用インタラクションシステムは、様々な方法で拡張可能です。

4-1. インタラクション可能な範囲の表示(HUD/Widget)

プレイヤーがインタラクト可能なオブジェクトに近づいた際、画面に「Eで開ける」といったヒントを表示するUIは、ゲームのユーザビリティを高めます。

4-2. 複数のインタラクションタイプ

単一の Interact 関数だけでなく、「Look (調べる)」「Use (使う)」「Pick Up (拾う)」など、複数のインタラクションタイプを持たせたい場合は、BPI_Interactable インターフェースに関数を追加するか、別のインターフェースを作成します。

例: BPI_Usable, BPI_Pickuppable といったインターフェースを分けて、オブジェクトの特性に応じて実装します。あるいは、Interact 関数に InteractionType (Enum型) の引数を追加し、イベント内でその型に応じて処理を分岐させることも可能です。

4-3. 構造体を使ったインタラクション情報の受け渡し

より複雑なインタラクション情報を渡したい場合(例: 拾うアイテムのID、ダメージ量など)、Struct を作成して Interact 関数の引数として渡すことが非常に有効です。これにより、単一の引数で複数の関連情報を一括で渡すことができ、Blueprintグラフを簡潔に保てます。

結論

この記事では、Unreal EngineのBlueprint Interfaceを活用することで、汎用的かつ拡張性の高いオブジェクトインタラクションシステムを構築する方法を解説しました。プログラミング経験のある読者の方々にとって、Blueprint Interfaceはオブジェクト指向プログラミングにおけるインターフェースの概念と非常に似ており、疎結合なシステム設計を実現するための強力なツールであることをご理解いただけたかと思います。

このシステムを基盤として、HUDによるインタラクションヒントの表示、複数のインタラクションタイプの追加、構造体を用いた詳細な情報の受け渡しなど、様々な機能を追加することで、よりリッチでインタラクティブなゲーム体験を創出することが可能です。ぜひ、ご自身のプロジェクトでこの知識を応用し、効率的なゲーム開発を進めてください。