0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UnrealEngine InterfaceとEventDispatcherの嬉しさを解説する

Posted at

はじめに

この記事はK3 Advent Calendar 2025の5日目です。
UE初心者の壁のひとつであるところのInterfaceとEventDispatcherについて、その存在の嬉しさがわかる実装例を元に解説していきたいと思います!
注意として、InterfaceとEventDispatcher自体がある程度どんなものかは知っている前提で解説していきます。「機能としては知ってるけど、どういうときに使ったらいいんだろう?」となっている人が本記事のターゲットになります。
実装には、UE5.6のThirdPersonTempleteを使用します。

Interfaceの嬉しさ

ギミックを動かすスイッチの作成を例に解説していきたいと思います!
アクションゲームにありがちなアレです。スイッチを押すと、ドアを開けたり、リフトを動かしたり、いろいろできる感じのものを想定します。

Interfaceを使わない場合の実装

まず、以下のクラスを作ります。他BPとの通信部分は後で。

  • スイッチ用クラスBP_Switch
    適当にスイッチっぽい見た目と、プレイヤーに反応するコリジョンを設定しておいて、BeginOverlapイベントを用意しておきます。
    image.png

  • 開けるドア用クラスBP_Door
    適当なドアっぽい見た目と、ドアを開くイベントOpenを作ります。
    image.png

  • 動かすリフト用クラスBP_Lift
    適当なリフトっぽい見た目と、リフトを動かすイベントStartMoveを作ります。
    image.png

では、まずはスイッチを踏むとドアが動く処理を作っていきます。
BP_SwitchにActorの参照型変数TargetActorを作って、InstancedEditableにします。(画像の瞼を開く)
図1.png
そして、BeginOverlapイベントでTargetActorをBP_Doorにキャストし、Openイベントを呼び出します。
image.png

そしたら、BP_SwitchとBP_Doorをレベルに置いて、置いたBP_SwitchのTargetActor変数にBP_Doorを指定します。(画像の赤線部分)
image.png

プレイしてスイッチを踏むとドアが開きますね。

では、次に同じBP_Switchクラスを使ってリフトを動かせるようにしましょう。
BP_DoorへのキャストのノードのCastFailedから伸ばして、今度はBP_Liftにキャストし、StartMoveイベントを呼び出します。
image.png

そうしたら、BP_Liftと新しいBP_Switchをレベルに置いて、新しいBP_SwitchのTargetActor変数をBP_Liftに変更します。
image.png
プレイして新しいスイッチを踏むと今度はリフトが動きます。

はい、ここまでで勘の良い方はお気づきかと思いますが、このやり方をするとスイッチで動かしたいものが増えるたびにBP_Switchの分岐がどんどん増えていきます。地獄ですね。
image.png

じゃあ、ドア専用スイッチ、リフト専用スイッチ…というようにスイッチのクラスを分ければいいと思う人もいるかもしれませんが、その方法でも動かしたいものが増えるたびにクラスが増えていってどのみち地獄です。
image.png

こんな地獄を解消してくれるのがInterfaceです!

Interfaceを使う場合の実装

用意するクラスは先ほどと同じです。
新しく、BPI_Gimmickという名前でブル―プリントインターフェースを作成します。
そして、Activateという名前の関数を定義します。
image.png

そうしたら、BP_DoorとBP_LiftにBPI_GimmickをImplementし、ActivateにそれぞれOpenとStartMoveを繋げます。
image.png

image.png

BP_Switchの方は、OverlapイベントでTargetActorからActivateを呼び出します。
さっきと比べて、随分コードがスッキリしたのがわかると思います。
image.png
これで実行してみると、なんと先ほどと同じ挙動になっています!
これで動かしたいギミックがどれだけ増えても、BP_Switchの実装を変更する必要がなくなりました!地獄のスパゲッティBPを書いたり、クラスが死ぬほど増えたりしません!嬉しいですね!

また、TargetGimmickを配列にしてあげれば、1つのスイッチで複数のギミックを動かすことも可能になります。
image.png
一つのスイッチのTargetGimmick変数に、BP_DoorとBP_Liftを両方設定
image.png

EventDispatcherの嬉しさ

プレイヤーキャラクターが近くにいるとき、プレイヤーのジャンプに反応して自分もジャンプする敵エネミーの作成を例に解説していきたいと思います!
マリオとかでよく見るアレですね。

EventDispatcherを使わない場合の実装

まず、Characterを継承したBP_Enemyを作ります。
スケルタルメッシュに適当にMannyを設定するなどしましょう。
そして、5m×5m×2m四方のBoxCollisonも追加します。これがプレイヤーを探知する範囲になります。
image.png

では、次にプレイヤーが範囲内に居るかどうか判定する処理を書いていきます。
プレイヤーが範囲内にいるかどうかを判定するbool型変数PlayerOverlapedを作り、BoxCollisionのBeginOverlapとEndOverlapに↓のような処理を追加します。
image.png

では、次にプレイヤーがジャンプした瞬間を判定して、自身をジャンプさせる処理です。
プレイヤーがジャンプした瞬間の判定には、Characterがデフォルトで持っている、現在のジャンプが何段目をカウントするJumpCurrentCountを用います。
Tickで毎フレームJumpCurrentCountを監視し、0から1以上になったタイミングで、PlayerOverlapedがtrueならジャンプをさせます。BPは↓のような感じになります。
image.png
これでBP_Enemyをレベルに置いて、近くでジャンプをしてみましょう。するとEnemyもジャンプするかと思います。

ただ、この実装、だいぶ気持ち悪いな…と思ったかと思います。特に、ジャンプをしたかどうかの判定のために、Tickで毎フレームJumpCurrentCountを監視するという所が非直感的かつ周りくどい手段を取っていて今後バグを生みそうですし、Tickを使ってるので処理も重たいです。
プレイヤーキャラクターの方の実装をいじって、「現在ジャンプ中」かを判定するフラグを作っても良いですが、どのみちTickを使って監視をするという点は変わりません。

もっとシンプルに、「プレイヤーがジャンプしたタイミング」でイベントを実行できたら良さそうだと思いませんか?それを実現してくれるのがEventDispatcherです。

EventDispatcherを使う場合の実装

まず、プレイヤーのBPである、BP_ThirdPersonCharacterで、EventDispatcherを追加し、名前をED_OnJumpedとします。そして、Jumpノードの後ろにCall ED_OnJumpedノードを追加します。
image.png

そして、BP_Enemyに戻ります。
まず、Tickにごちゃごちゃ書いたBPを全て消去し、BeginOverlapとEndOverlapを↓のように変更します。
image.png

プレイヤーが探知範囲内に入ったときに、ED_OnJumpedに、JumpイベントをBindし、探知範囲から抜けたときはUnbindするという操作を行っています。
つまり、Bind中に、BP_ThirdPersonCharacterでBP_ED_OnJumpedがcallされると、それに連動してBP_EnemyもJumpをするということですね。
実際に、この状態でプレイしてみると、先ほどと同じ挙動になっていることがわかります。

このように、EventDispatcherを使えば、「○○が○○した時」のタイミングを別のBPクラスでも簡単に、直感的にとることができます。Tickも使用しないので処理負荷的にも非常に嬉しいのがわかると思います。

まとめ

このように、InterfaceとEventDispatcherはちゃんと使えると処理負荷、可読性、保守性、拡張性などなどが非常に良くなる嬉しい性質を持ってます。適切に使って快適な開発ライフを送りましょう!

おまけとして、InterfaceとEventDispatcherを使うと幸せになれる場面を他にも何例か紹介しようと思います。どう使えば嬉しくなれるかを考えてみてください!

Interface

  • 種類が多く、固有の効果があるアイテムの実装
  • プレイヤーの目の前にある物体へのインタラクション
  • 固有効果を持っている武器、防具の実装

EventDispatcher

  • ゲームの進行度合いに応じてステージから消えたり出現したりするアイテム
  • ゲーム中一度だけしか発生しないイベント
  • 所持アイテムやステータスが変更された時のUIの更新
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?