【Unreal Engine】Event TickをやめてTimerとイベントで設計する方法

作成: 2025-12-12

Event Tickは毎フレーム実行されるため、多用するとパフォーマンスに影響する。Timer、Event Dispatcher、Collision Eventsを使った代替設計を紹介。

Event Tickのパフォーマンス問題

Blueprintの 「Event Tick(イベントティック)」 ノードは、毎フレーム実行されるため便利ですが、この「毎フレーム実行」こそがパフォーマンスを蝕む要因となります。

本記事では、Event Tickを最小限に抑えて高性能なゲームロジックを構築するための 「Tick-less(ティックレス)設計」 を解説します。

Event Tickのコストと問題点

Event Tickの仕組みとコスト

Event Tickは、ActorやComponentがアクティブである限り、毎フレーム 実行されるイベントです。例えば、ゲームが60FPS(Frames Per Second)で動作している場合、Event Tickは1秒間に60回実行されます。

このノードに接続されたロジックは、そのフレームで必ず処理されます。もし、100体の敵キャラクターがそれぞれEvent Tickで複雑なAI処理や距離チェックを行っていたらどうなるでしょうか?

たとえTick内の処理が非常に軽くても、Actorの数が増えるほど、その処理回数は爆発的に増加し、CPUに大きな負荷をかけます。特にBlueprintはC++に比べて実行速度が遅いため、この負荷は顕著になります。

よくある間違い:Tickで「ポーリング」を行う

初心者がEvent Tickを使いがちな典型的な例は、ポーリング(Polling) です。

例:プレイヤーとの距離を常にチェックする

// Event Tick -> Get Distance To Player -> Branch (Distance < 500) -> Do Something

この処理は、プレイヤーが近くにいようがいまいが、毎フレーム実行されます。プレイヤーが遠くにいる99%の時間も、無駄な距離計算が走り続けているのです。


Tick-less設計の代替手段

高性能な設計の鍵は、「必要な時に、必要な処理だけを実行する」 というイベント駆動型(Event-Driven) の考え方に切り替えることです。

Event Tickのように「常にチェックする」のではなく、「何かが起こった時だけ」処理を実行するようにします。

代替手段1:周期的な処理には「Timer(タイマー)」を使う

毎フレームである必要はないが、定期的に実行したい処理(例:AIのターゲット再検索、一定時間ごとの回復処理など)には、Timerノードを使用します。

Timerは、指定した時間間隔(例:0.5秒ごと)でイベントや関数を呼び出すことができます。

Blueprint例:0.5秒ごとにHPを回復する

// Event BeginPlay
//   -> Set Timer by Event
//      - Event: Custom Event (Heal Over Time)
//      - Time: 0.5
//      - Looping: True
//
// Custom Event (Heal Over Time)
//   -> Add Health (e.g., +1)

この方法なら、60FPSの環境でEvent Tickが1秒間に60回実行されるのに対し、Timerはわずか2回しか実行されません。大幅な負荷軽減になります。

代替手段2:Actor間の通信には「Event Dispatcher(イベントディスパッチャー)」を使う

Actor AがActor Bの状態を常に監視(ポーリング)する代わりに、Actor Bで状態が変化したときにイベントを通知 するようにします。これがEvent Dispatcherです。

例:ドアが開いたことを通知する

  1. ドアActor: ドアが開く処理の最後にEvent Dispatcher(例: OnDoorOpened)を呼び出す。
  2. プレイヤーActor: OnDoorOpenedイベントに処理(例: ログ表示)をバインド(Bind) しておく。
// [ドアActor]
// Event Open Door -> ... (Open Door Logic) ... -> Call OnDoorOpened

// [プレイヤーActor]
// Event BeginPlay -> Get Door Reference -> Bind Event to OnDoorOpened -> Custom Event (Door Opened Handler)

これにより、ドアが開くという「イベント」が発生した瞬間にのみ、関連する処理が実行されます。

代替手段3:物理的な検出には「Collision Events(コリジョンイベント)」を使う

前述の「プレイヤーとの距離を常にチェックする」という問題は、Event Tickではなく、Unreal Engineに組み込まれた物理エンジンイベントで解決できます。

例:トリガーボリュームに入ったことを検出する

  1. トリガーボリューム: On Component Begin Overlapイベントを使用する。
  2. ロジック: このイベントから処理(例: UI表示、ダメージ適用)を実行する。
// [トリガーボリュームComponent]
// On Component Begin Overlap (Other Actor is Player)
//   -> Do Something (e.g., Apply Damage)

このイベントは、Actorが実際に重なり合った瞬間に一度だけ、または重なりが終了した瞬間に一度だけ実行されます。Event Tickで毎フレーム距離を計算するよりも、はるかに効率的です。


Tickが必要な場合の最適化

移動やカメラ制御など、どうしても毎フレームの更新が必要な処理も存在します。その場合は、以下の最適化を適用します。

ベストプラクティス:Tickの実行間隔を調整する

Actorのプロパティにある 「Tick Interval(ティック間隔)」 を設定することで、Tickの実行頻度を下げることができます。

  • デフォルト: 0.0(毎フレーム実行)
  • 設定例: 0.1(1秒間に10回実行)

AIの索敵など、多少の遅延が許容される処理であれば、この設定でパフォーマンスを大幅に改善できます。

ベストプラクティス:Tickを必要な時だけ有効/無効にする

Actorが画面外にいる、またはAIが待機状態にあるなど、Tick処理が不要な状態では、Tickを無効化します。

// Tickを無効化
// Set Actor Tick Enabled (New Tick Enabled: False)

// Tickを有効化
// Set Actor Tick Enabled (New Tick Enabled: True)

例えば、敵AIがプレイヤーを見失った場合、Tickを無効化し、Timerで数秒おきに索敵処理だけを実行するように切り替えることで、アイドル時の負荷をゼロに近づけることができます。

応用:Tick GroupとLatent Action

より高度な制御が必要な場合、以下の機能も活用できます。

💡 Tick Group(ティックグループ)

Tickの実行順序を制御するための仕組みです。ActorのプロパティでTick Groupを設定できます:

  • PrePhysics: 物理シミュレーション前に実行(移動入力の処理など)
  • DuringPhysics: 物理シミュレーション中に実行
  • PostPhysics: 物理シミュレーション後に実行(物理結果に基づく処理)

依存関係のある処理の順序を保証したい場合に有効です。

💡 Latent Action(DelayやTimelineなど)

DelayノードやTimelineは、Tickを使わずに時間経過に基づく処理を実現する強力な代替手段です:

  • Delay: 指定秒数後に処理を再開
  • Timeline: 時間経過に応じた値の補間(ドアの開閉、フェードイン/アウトなど)

これらはEvent Graphで使用でき、Tick-less設計を維持しながら時間ベースの処理を実装できます。


Tick代替手段のまとめ

Event Tickは強力ですが、ゲーム全体のパフォーマンスを考慮すると、その使用は 「本当に毎フレーム必要か?」 という問いに「Yes」と答えられる場合に限定すべきです。

Tick代替手段用途実行頻度
Timer定期的な処理(回復、AIの周期的なチェック)指定した間隔(例: 0.5秒ごと)
Event DispatcherActor間の非同期通信(状態変化の通知)イベント発生時のみ
Collision Events物理的な接触、範囲検出接触・離脱の瞬間のみ
Tick Interval毎フレーム処理が必要だが、頻度を下げられる場合指定した間隔(例: 0.1秒ごと)

Tick-less設計を意識することで、あなたのUnreal Engineプロジェクトはより高速に、より安定して動作するようになるでしょう。パフォーマンスを意識した設計は、プロのテクニカルライターへの第一歩です。