14.

UE5のEvent Tickノードの使い方|毎フレーム処理とDelta Seconds

編集

Unreal Engine 5(UE5)のEvent Tickノードは、毎フレーム実行されるイベントノードで、これを使って継続的な処理(回転、移動、カウントダウンなど)をイベントグラフに書きます。再生中、フレームが描画されるたびにこのノードから実行ピンが発火するため、「常に更新し続けたい処理」を接続するのが基本的な使い方です。ノードが扱う概念そのものの詳細は Event Tick も参照してください。本記事ではノードとしての出し方・配線・設定に焦点を当てます。

この記事の要点
  • Event Tickノードは毎フレーム発火するイベントノード。ブループリントの継続処理の起点になる。
  • 出力のDelta Secondsピンは前フレームからの経過秒数。これを掛けることでフレームレートに依存しない動きを作れる。
  • イベントグラフで右クリックし「Event Tick」を検索すると配置できる(1グラフに1つ)。
  • 不要なときはSet Actor Tick Enabledで無効化、クラス設定のStart with Tick Enabled / Can Ever Tickで初期状態を制御。
  • Tick Intervalで実行間隔を間引ける。毎フレーム不要な処理はTimerでの代替も検討する。
  • Tickは件数が増えるとパフォーマンスに直結する。重い処理を毎フレーム回さない設計が重要。

Event Tickノードとは

Event Tickノードは、アクター(Actor)やコンポーネントに紐づき、ゲームのフレームレートに応じて毎フレーム1回実行されるイベントノードです。たとえば60FPSの環境ではおおよそ1秒間に60回、120FPSなら120回実行されます。実行回数がフレームレートに左右される点が大きな特徴で、後述のDelta Secondsを使わないと、PCの性能次第で動きの速さが変わってしまいます。

ノードの見た目は、左側に実行ピン(白い三角の出力)、そしてDelta Secondsという浮動小数点(float)の出力ピンを1つ持ちます。このDelta Secondsが、フレームレート非依存の処理を書くうえでの要になります。

Event Tickノードの出し方

Event Tickノードはブループリントのイベントグラフに配置します。手順は次のとおりです。

1. Blueprint Class(Actorを親クラスにしたものなど)を開く。

2. イベントグラフ(Event Graph)の何もない場所で右クリックする。

3. 表示される検索ボックスに「Event Tick」と入力し、候補から選択する。

4. 配置されたEvent Tickノードの実行ピンから、行いたい処理のノードへ線をつなぐ。

新規のActorブループリントには、最初からコメント化されたEvent Tickノードがグラフ上に置かれていることもあります。その場合は右クリックから新規配置せず、既存のノードを使います。Event Tickは1つのイベントグラフに1つだけ配置でき、同じグラフに2つ目を置くことはできません(同名イベントの重複は不可)。

Delta Secondsピンの使い方

Delta Secondsは「前のフレームから今のフレームまでに経過した秒数」です。60FPSで安定していれば毎フレームおよそ0.0167秒、30FPSなら約0.0333秒になります。移動量や回転量にこの値を掛けることで、フレームレートが変わっても1秒あたりの変化量を一定に保てます。

たとえば「1秒間に300ユニット前進させたい」場合は、速度300にDelta Secondsを掛けた値を1フレームの移動量として使います。これにより、重い場面でフレームレートが落ちても、見かけの速度はおおむね一定になります。

// 1フレームの移動量 = 速度 × Delta Seconds

移動量 = 300(ユニット/秒) * DeltaSeconds

新しい位置 = Get Actor Location + (前方ベクトル × 移動量)

Set Actor Location に新しい位置を渡す

ブループリントでは、Event TickのDelta Secondsピンを乗算(multiply)ノードへつなぎ、その結果をSet Actor Locationなどの設定ノードに渡す配線になります。Delta Secondsを掛け忘れると、フレームレートが高いPCほど速く動くという、フレームレート依存の不具合の原因になります。

Tickの有効化・無効化

常に毎フレーム動かす必要がない場合は、Tick自体をオン・オフして無駄な処理を減らせます。制御方法は大きく2種類あります。

実行時に切り替える(Set Actor Tick Enabled)

Set Actor Tick Enabledノードを使うと、ゲーム実行中にそのアクターのTickを有効・無効に切り替えられます。たとえば「画面外に出たらTickを止め、近づいたら再開する」といった制御に使います。

Set Actor Tick Enabled(New Tick Enabled = false) // Tickを止める

Set Actor Tick Enabled(New Tick Enabled = true) // Tickを再開する

初期状態をクラス設定で決める

ブループリントのClass Defaults(クラスのデフォルト設定)には、Actor Tickに関する項目があります。代表的なものは次のとおりです。

設定項目役割
Start with Tick Enabledゲーム開始時にTickを有効にするか。オフにしておき、必要になってからSet Actor Tick Enabledで有効化する使い方ができる。
Tick Interval (secs)Tickの実行間隔(秒)。後述。

なお、C++クラスには「そもそもTickできるかどうか」を表すCan Ever Tick(PrimaryActorTick.bCanEverTick)という設定があります。これが無効だと、ブループリント側でEvent Tickをつないでも発火しません。C++を親クラスにしている場合は、ここが有効になっているかも確認しておくとよいでしょう。Tickをまったく使わないアクターでこれを無効にしておくと、わずかながらオーバーヘッドを減らせます。

Tick Intervalで実行頻度を下げる

毎フレームほどの頻度が不要な処理では、Tick Interval (secs)を設定して実行間隔を空けられます。たとえば0.2を設定すると、おおよそ0.2秒ごとにEvent Tickが発火するようになり、実行回数を大きく減らせます。HPの自動回復チェックや、距離に応じた表示切り替えなど、毎フレームの精度が要らない処理に向いています。

Tick Intervalを使う場合の注意点として、このときのDelta Secondsは「前回Tickが実行されてからの経過時間」になります。つまり間隔を空けた分だけDelta Secondsの値も大きくなるため、Delta Secondsを掛けた計算であれば、間隔を変えても1秒あたりの変化量はおおむね保たれます。値を0にすると毎フレーム実行(デフォルト相当)になります。

具体例

例1:オブジェクトを回転させ続ける

毎フレーム少しずつ回転を加えると、滑らかに回り続けるオブジェクトを作れます。配線の流れは次のとおりです。

1. Event TickのDelta Secondsを取得する。

2. 1秒あたりの回転速度(例:Yaw 90度/秒)にDelta Secondsを掛け、1フレーム分の回転量を求める。

3. その回転量をAdd Actor Local Rotation(または Add Actor World Rotation)に渡す。

こうすると、フレームレートに関わらず「1秒で90度」という一定の速さで回転します。

例2:カウントダウン

残り時間を毎フレーム減らしていくカウントダウンも、Event Tickの典型的な使い道です。

1. 残り時間を保持するfloat変数(例:RemainingTime)を用意する。

2. Event Tickで、RemainingTimeからDelta Secondsを引いた値を再びRemainingTimeに代入する。

3. RemainingTimeが0以下になったら、時間切れの処理を呼び出し、必要ならSet Actor Tick Enabledで以降のTickを止める。

ただし、こうした「一定時間後に何かする」だけの処理であれば、毎フレーム数値を引き続けるより、次に述べるTimerのほうが軽量で素直に書けることも多いです。

パフォーマンス上の注意とTickを使わない代替

Event Tickは便利な一方、毎フレーム実行されるためコストが高い処理でもあります。多数のアクターがそれぞれ重いTick処理を持つと、フレームレート低下の直接の原因になります。次の点に注意してください。

  • 重い処理を毎フレーム回さない:ライントレース、距離計算、検索処理などを全アクターが毎フレーム行うと負荷が大きい。Tick Intervalで間引くか、イベント駆動に置き換える。
  • 「一定時間ごと」「一定時間後」はTimerを検討Set Timer by Event / Set Timer by Function Name を使えば、指定した間隔(例:1秒ごと)でだけ処理を呼び出せる。毎フレーム判定するより軽く、意図も明確になる。
  • イベント駆動への置き換え:状態が変化した瞬間にだけ処理すれば足りる場合は、Tickで監視し続けるより、変化を通知するイベントやデリゲートで処理するほうが効率的。
  • 使わないTickはオフ:処理が不要な間はSet Actor Tick Enabledで無効化し、Tickが本当に必要なアクターだけ有効にする。

よくある落とし穴

つまずきやすいポイント
  • Delta Secondsを掛け忘れる:移動・回転にDelta Secondsを掛けないと、高フレームレートのPCほど速く動くフレームレート依存の挙動になる。動きに関わる計算では原則Delta Secondsを掛ける。
  • 重い処理をそのまま毎フレーム実行:上の注意box参照。負荷が出てから見直すのではなく、最初からTickに重い処理を載せない設計を意識する。
  • Tickが発火しない:C++親クラスでCan Ever Tickが無効、またはStart with Tick Enabledがオフのまま再有効化していない、といったケース。設定とSet Actor Tick Enabledの呼び出しを確認する。
  • 1グラフに複数のEvent Tickを置こうとする:Event Tickはイベントグラフごとに1つ。処理を分けたいときは、Event Tickから関数やマクロを呼び出して整理する。
  • 無効化したつもりで止まっていない:Set Actor Tick Enabledの対象アクターや、コンポーネント側のTick(Set Component Tick Enabled)を取り違えていないか確認する。

FAQ

Q. Event Tickは必ず毎フレーム呼ばれますか?
A. Tickが有効で、かつTick Intervalが0(デフォルト)なら、原則として毎フレーム呼ばれます。Tick Intervalを設定するとその間隔ごと、Set Actor Tick Enabledで無効化している間は呼ばれません。また、フレームレート自体が変動すれば呼ばれる回数(=1秒あたりの実行回数)も変わります。

Q. Tickを使わずに継続処理をするには?
A. 一定間隔の処理ならTimer(Set Timer by Event など)、状態変化のタイミングだけでよいならイベントやデリゲートでの通知が使えます。これらは毎フレーム実行しないぶん軽量で、目的に対して意図も明確になります。「本当に毎フレーム必要か」を一度考えてから、必要な場合にEvent Tickを使うのがおすすめです。

Q. Delta SecondsとGet World Delta Secondsは同じですか?
A. 多くの場面で同じ値(そのフレームのデルタ時間)を示しますが、Tick Intervalを設定したアクターのEvent TickのDelta Secondsは「前回そのアクターがTickされてからの経過時間」を表します。間引いている場合は両者が一致しないことがあるため、Event Tickでの計算には、原則そのEvent Tickが出力するDelta Secondsピンを使うのが安全です。

編集
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

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