3.

UE5のEvent Tickとは|Delta Secondsの使い方とパフォーマンス注意

編集

Event Tick(イベントティック)とは、Unreal Engine 5(UE5)でアクターやコンポーネントが有効な間、毎フレーム自動的に呼び出されるイベントです。フレームごとに繰り返し処理を実行できるため、滑らかな移動や回転、継続的な状態監視といったリアルタイム処理の基盤として使われます。ただし高頻度で実行される性質上、使い方を誤るとパフォーマンス低下の原因になりやすいため、後述する注意点と代替手段の理解が重要です。

この記事の要点
  • Event Tickは、有効なアクター・コンポーネントが存在する間、原則として毎フレーム呼び出されるイベント。
  • 出力ピンのDelta Seconds(前フレームからの経過秒数)を計算に掛けることで、フレームレートに左右されない動きを実現できる。
  • 滑らかな移動・回転・追従など、毎フレームの更新が本当に必要な処理に向く。
  • 重い処理を毎フレーム実行するとフレームレートが低下しやすいため、必要なときだけ実行する設計が大切。
  • 一定間隔で十分な処理はタイマー、特定の瞬間だけの処理はイベント駆動に置き換えると効率的。
  • Tick Intervalで実行間隔を間引いたり、Can Ever Tickを無効化したりして負荷を抑えられる。

Event Tickとは(毎フレーム実行されるイベント)

Event Tickは、アクターやアクターコンポーネント、ブループリントがレベル上で有効になっている間、毎フレーム呼び出されるイベントノードです。たとえばゲームが60fps(1秒間に60フレーム)で動作している場合、Event Tickはおおむね1秒間に60回実行されます。フレームが描画されるたびに処理を差し込めるため、時間の経過とともに連続的に変化させたい処理を記述するのに適しています。

ブループリントのイベントグラフで右クリックし、「Event Tick」と入力するとノードを配置できます。多くのアクター系ブループリントでは、既定でTickが有効になっているため、配置するだけで毎フレームの呼び出しが始まります。一方で、毎フレームの処理を一切行わないブループリントでもTickが有効なままになっていることがあり、これが無駄な負荷の原因になる場合があります。

なお、Event Tickが呼ばれる頻度はフレームレートに依存します。フレームレートは実行環境(PCやコンソールの性能、描画負荷など)によって変動するため、「毎フレーム=常に等間隔」とは限りません。重い場面では1秒あたりの呼び出し回数が減り、軽い場面では増えます。この変動を前提に処理を組むことが、後述するDelta Secondsの考え方につながります。

Delta Seconds(前フレームからの経過秒数)とフレームレート非依存の計算

Event TickノードにはDelta Secondsという出力ピンがあります。これは前のフレームから今回のフレームまでに経過した時間(秒)を表す値です。たとえば60fpsで安定して動作している場合、Delta Secondsはおおよそ0.0167秒(=1÷60)前後になります。フレームレートが下がって30fpsになれば、Delta Secondsはおよそ0.0333秒へと大きくなります。

このDelta Secondsを使う最大の目的は、フレームレートに左右されない(フレームレート非依存の)計算を実現することです。Event Tickは前述のとおりフレームレートによって呼ばれる回数が変わります。もしDelta Secondsを使わずに「毎フレーム一定量だけ動かす」処理を書くと、フレームレートが高い環境ほど速く、低い環境ほど遅く動いてしまい、動作速度が環境に依存してしまいます。

そこで、「1秒あたりの変化量 × Delta Seconds」という形で計算すると、フレームレートが変わっても1秒間あたりの変化量が一定に保たれます。考え方を整理すると次のようになります。

// 悪い例: 毎フレーム同じ量だけ加算(フレームレートに依存して速度が変わる)

NewLocation = CurrentLocation + Speed

 

// 良い例: 1秒あたりの速度に Delta Seconds を掛ける(フレームレート非依存)

NewLocation = CurrentLocation + Speed * DeltaSeconds

たとえば「1秒間に300ユニット進めたい」場合、Speedを300とし、毎Tickで「300 × Delta Seconds」だけ加算します。60fpsでも30fpsでも、1秒経過すれば合計でおよそ300ユニット進むため、見た目の移動速度が環境によってばらつきにくくなります。回転やフェード(透明度の変化)など、時間に比例して変化させたい処理は、同じ考え方でDelta Secondsを掛けるのが基本です。

使い方の例(滑らかな移動・回転)

Event TickとDelta Secondsを組み合わせると、毎フレーム少しずつ値を更新することで滑らかな表現を作れます。代表的な使い方を挙げます。

1. 滑らかな移動
オブジェクトを一定速度で動かしたい場合、現在位置に「方向ベクトル × 速度 × Delta Seconds」を加算した位置をSet Actor Locationなどで設定します。Delta Secondsを掛けているため、フレームレートが変動しても移動速度が安定します。

2. 滑らかな回転
毎フレームAdd Actor Local Rotationなどで「1秒あたりの回転角 × Delta Seconds」だけ回転を加えると、一定の角速度で回り続ける表現になります。看板やアイテムの常時回転、カメラのゆるやかな旋回などに使えます。

3. 追従・補間
ターゲットへ徐々に近づける補間処理(位置や回転を少しずつ目標値へ寄せる)にもEvent Tickがよく使われます。補間用のノードに経過時間としてDelta Secondsを渡すことで、フレームレートが違っても近づき方の速さがそろいやすくなります。

4. 時間に応じた状態更新
エフェクトの強度や音量を時間とともに変化させる、クールダウンの残り時間を毎フレーム減らすといった、連続的な値の更新にも向いています。これらもDelta Secondsを掛けて「1秒あたりの変化量」として扱うのが基本です。

パフォーマンス注意(毎Tickで重い処理をしない)

Event Tickは便利な一方、毎フレーム実行されるという性質そのものがコストになります。1回あたりの処理が軽くても、フレームごとに繰り返され、さらに多数のアクターが同時にTickしていれば、全体としては無視できない負荷になります。フレームレートの低下やカクつきの原因になりやすいため、次の点を意識してください。

重い処理を毎Tickに置かない。 ライントレース(レイキャスト)の多用、広範囲の検索(GetAllActorsOfClassなど)、文字列処理、複雑な計算などは負荷が大きくなりがちです。これらは毎フレームではなく、必要なときだけ実行するのが原則です。

必要なときだけ実行する。 「毎フレーム監視」したくなる処理でも、実際には状態が変わった瞬間だけ処理すれば十分なことが多いです。条件が変化したときに通知される仕組み(イベント駆動)へ置き換えられないか、まず検討します。どうしてもTickで監視する場合は、早い段階で条件分岐し、不要なら以降の処理をスキップします。

使わないTickは無効にする。 毎フレームの処理を行わないブループリントは、後述のCan Ever Tickを無効にしておくと、無駄なTick呼び出し自体をなくせます。塵も積もれば負荷になるため、使っていないTickは切るのが基本的な最適化です。

Tickを使わない代替手段(タイマー/イベント駆動)との比較

「一定時間ごと」や「特定の瞬間だけ」で十分な処理は、Event Tick以外の手段に置き換えるとパフォーマンス面で有利です。主な選択肢を比較します。

手段実行タイミング向いている処理負荷の傾向
Event Tick毎フレーム滑らかな移動・回転・補間など連続的な更新高頻度なため負荷が高くなりやすい
タイマー(Set Timer by ~)指定した間隔ごと一定間隔の定期チェック、クールダウン管理間隔を空けるほど負荷を抑えやすい
イベント駆動(カスタムイベント/ディスパッチャー)条件が発生した瞬間のみ状態変化や入力など「起きたとき」の処理必要時のみ実行されるため低負荷
Sequencer / アニメーションタイムラインに沿ってあらかじめ決まった時間制御の演出手動のフレーム処理を減らせる

たとえば「1秒ごとに敵との距離をチェックする」ような処理は、毎フレームのEvent Tickよりもタイマーで間隔を空けて実行するほうが負荷を抑えられます。「ボタンが押された」「ダメージを受けた」のように発生が不定期なものは、カスタムイベントやイベントディスパッチャーによるイベント駆動のほうが自然で効率的です。一方、毎フレームの滑らかさが本当に必要な処理だけをEvent Tickに残す、という切り分けが基本方針になります。

Tick間隔の設定(Tick Interval)

「毎フレームほどの頻度は要らないが、定期的には実行したい」という場合、Tick Interval(ティックの実行間隔、秒)を設定して呼び出し頻度を間引けます。ブループリントのクラスデフォルトや詳細パネルで、Tickに関する設定としてTick Interval(secs)を指定できます。

Tick Intervalを0にすると毎フレーム呼び出し(既定の動作)になります。たとえば0.2と指定すると、約0.2秒ごとにEvent Tickが呼ばれるようになり、毎フレームよりも実行回数を大きく減らせます。

注意点として、Tick Intervalを設定した場合、Event Tickに渡されるDelta Secondsは「前回のTickからの経過時間」になります。つまり間隔を空けた分だけDelta Secondsの値も大きくなります。前述のとおり「変化量 × Delta Seconds」の形で計算していれば、間隔を変えても1秒あたりの変化量はおおむね保たれます。ただし、間隔を大きくすると更新が粗くなり、移動や監視の反応がカクつく・遅れる場合があるため、滑らかさと負荷のバランスを見て調整します。

落とし穴と対処

落とし穴内容と対処
毎Tickの負荷の蓄積1回が軽くても毎フレーム×多数のアクターで負荷が積み上がる。重い処理はTickから外し、使わないTickは無効化する。
Delta Seconds未使用でフレーム依存毎フレーム固定量を加算すると、フレームレートが高い環境ほど速く動く。移動・回転・時間変化には必ずDelta Secondsを掛ける。
Can Ever Tickが無効でTickが動かないTickを使いたいのにEvent Tickが呼ばれない場合、クラス設定の「Can Ever Tick」が無効になっていないか確認する。逆に使わない場合は意図的に無効化しておく。
初期状態でTickが無効「Start with Tick Enabled(開始時にTickを有効化)」が外れていると、開始時点ではTickが動かない場合がある。必要に応じて有効化、または実行中にTickの有効・無効を切り替える。
重い処理を毎フレーム監視広範囲検索やトレースを毎Tickで行うと負荷が大きい。タイマーで間隔を空ける、イベント駆動に置き換えるなどを検討する。

とくにCan Ever Tickは、Tickの有効・無効を根本から決める設定です。これが無効だとEvent Tickノードを置いても呼び出されません。「Tickが動かない」というときは、まずこの設定を確認するのが定石です。反対に、Tickを一切使わないブループリントでは、Can Ever Tickを無効にしておくことが無駄な負荷を避ける有効な手段になります。

よくある質問(FAQ)

Q1. Event Tickは必ず60回/秒で呼ばれますか?
いいえ。呼び出し頻度はフレームレートに依存します。60fpsならおおむね1秒間に60回ですが、描画負荷が高い場面ではフレームレートが下がり、呼び出し回数も減ります。等間隔・固定回数を前提にせず、Delta Secondsを使って時間ベースで計算するのが安全です。

Q2. なぜDelta Secondsを掛ける必要があるのですか?
フレームレートが環境やシーンによって変わるためです。Delta Seconds(前フレームからの経過秒)を掛けて「1秒あたりの変化量」として扱うことで、フレームレートが高い環境でも低い環境でも、1秒間あたりの動きや変化の量がそろいやすくなります。掛けないと、動作速度が環境に依存してしまいます。

Q3. Event Tickはできるだけ使わないほうがよいのですか?
一概に禁止すべきものではありません。滑らかな移動・回転・補間など、毎フレームの更新が本当に必要な処理にはEvent Tickが適しています。問題になるのは、一定間隔や特定の瞬間で十分な処理まで毎フレーム実行してしまうケースです。その場合はタイマーやイベント駆動へ置き換え、本当に必要な処理だけをTickに残す、という使い分けが望ましい方針です。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Event BeginPlay
  2. Event ActorBeginOverlap
  3. Event Tick
  4. on component begin overlap
  5. On Component Hit
  6. CameraBoom(Spring Arm)
  7. Get Player Character
  8. Nav Mesh Bounds Volume
  9. AI MoveTo
  10. Pawn
  11. Create Render Target 2D
  12. Take High Res Screenshotノード
  13. Sphere Reflection Capture
  14. Event Tickノード
  15. ウィジェットのキャンバスパネル
  16. DefaultSceneRoot
  17. FloatingPawnMovement
  18. Set World Rotation
  19. Event Any Damage
  20. Set World Rotation
  21. VInterp To
  22. Get Socket Transform

最近更新/作成されたページ