38.

UE5のタイマー処理(Set Timer)|Looping・Tickとの違いと解除方法

編集
この記事の要点
  • 一定間隔で処理を呼ぶには Set Timer by Function Name または Set Timer by Event
  • Tick 毎フレーム より軽量。CPU 負荷を抑えられる
  • 解除は Clear Timer、確認は Is Timer Active / Get Timer Remaining Time
  • C++ は GetWorldTimerManager().SetTimer(Handle, this, &FuncPtr, Rate, Looping)
  • Delay ノードは Latent 関数で Blueprint 専用、Timer とは別物

Set Timer の基本

Unreal Engine で一定間隔で処理を実行する標準手段は Set Timer ノードです。Tick イベントで毎フレーム判定するよりCPU 効率が良く、呼び出し間隔を制御できます。

Set Timer by Function Name(旧来型)

[Blueprint Node]
Set Timer by Function Name
  Object        = Self
  Function Name = "OnPeriodicAttack"   ← 文字列で関数名を指定
  Time          = 1.0                    ← 何秒ごとに
  Looping       = true                   ← 繰り返すか
  Initial Start Delay = 0.0
  Initial Start Delay Variance = 0.0

[戻り値]
Timer Handle (構造体)  → Clear に必要なので変数で保存

Function Name は文字列で指定するため、関数名のリネームで動作不能になるリスクがあります。新しい Set Timer by Event 推奨。

Set Timer by Event(推奨)

[Blueprint Node]
Set Timer by Event
  Event   = Custom Event の Delegate ピン
  Time    = 1.0
  Looping = true

[使い方]
1. Custom Event を作る (例: "OnPeriodicAttack")
2. Set Timer by Event ノードの Event ピンに RED の Custom Event を接続
3. Looping = true で繰り返し
4. 戻り値 Timer Handle を変数に保存

メリット: Event をリネームしても自動追従、コンパイル時にエラー検出可

Timer Handle の保存と解除

[BeginPlay]
Set Timer by Event (Event = E_Attack, Time = 2, Looping = true)
  → 戻り値 Timer Handle を変数 "AttackTimerHandle" にセット

[OnDeath などのイベント]
Clear Timer by Handle (Handle = AttackTimerHandle)
  → タイマー停止

[判定]
Is Timer Active by Handle → bool
Get Timer Remaining Time by Handle → 残り秒
Get Timer Elapsed Time by Handle   → 経過秒

C++ での Timer 操作

// AMyActor.h
UCLASS()
class MYGAME_API AMyActor : public AActor
{
    GENERATED_BODY()
public:
    virtual void BeginPlay() override;
    virtual void EndPlay(const EEndPlayReason::Type Reason) override;

    void OnPeriodicTick();

private:
    FTimerHandle PeriodicTimerHandle;
};

// AMyActor.cpp
void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    // 2 秒ごとに OnPeriodicTick を呼ぶ
    GetWorldTimerManager().SetTimer(
        PeriodicTimerHandle,    // ハンドル
        this,                    // Target Object
        &AMyActor::OnPeriodicTick,
        2.0f,                    // Rate
        true                     // bLoop
    );

    // ラムダで関数を直接記述
    FTimerHandle TempHandle;
    GetWorldTimerManager().SetTimer(
        TempHandle,
        [this](){ UE_LOG(LogTemp, Log, TEXT("3秒経過")); },
        3.0f,
        false                    // 一度だけ
    );

    // 5 秒後に 1 回だけ呼ぶ
    GetWorldTimerManager().SetTimerForNextTick(
        [this](){ UE_LOG(LogTemp, Log, TEXT("次フレーム")); });
}

void AMyActor::EndPlay(const EEndPlayReason::Type Reason)
{
    // タイマー解除(しないと OnPeriodicTick が呼ばれ続けてクラッシュ要因)
    GetWorldTimerManager().ClearTimer(PeriodicTimerHandle);
    Super::EndPlay(Reason);
}

void AMyActor::OnPeriodicTick()
{
    UE_LOG(LogTemp, Log, TEXT("2秒ごとの処理"));
}

Set Timer / Tick / Delay の比較

Set TimerTickDelay
呼び出し頻度指定秒ごと毎フレーム1 回のみ
CPU コスト
停止可能性Clear Timer で停止Tick Enabled を切り替え不可(実行開始したら待つ)
Pause 中停止する(既定)停止する停止する
使い所定期更新、攻撃クールダウン毎フレーム必要な処理1 回だけ遅延実行
C++ 対応○ FTimerHandle○ Tick()× Blueprint 専用

Delay ノードとの違い

Blueprint の Delay は Latent 関数で、その実行ピンが「N 秒後に発火」するだけ。再利用や停止は不可で、Custom Event の途中に挟む用途。定期実行には Set Timer1 回限りなら Delay

使用例: 攻撃クールダウン

void AEnemyAI::StartAutoAttack()
{
    GetWorldTimerManager().SetTimer(
        AttackHandle,
        this,
        &AEnemyAI::FireBullet,
        AttackInterval,   // 例: 1.5 秒
        true);
}

void AEnemyAI::StopAutoAttack()
{
    GetWorldTimerManager().ClearTimer(AttackHandle);
}

void AEnemyAI::FireBullet()
{
    // 弾を発射
}

使用例: ダメージのチック (Tick Damage)

毒沼に入っている間、1 秒ごとにダメージを与える:

[Trigger Volume]
[OnComponentBeginOverlap]
  → Set Timer by Event (Event = E_Tick, Time = 1, Looping = true)
  → Save Handle in PoisonHandle

[E_Tick] (Custom Event)
  Apply Damage to OtherActor (Damage = 5)

[OnComponentEndOverlap]
  → Clear Timer by Handle (PoisonHandle)

Behavior Tree の Wait タスク

BT 内では Wait タスクで時間経過を表現します。Set Timer は不要:

Sequence "巡回"
├ Move To (PatrolLocation)
├ Wait (Random 2-5s)
├ Move To (NextLocation)
└ Wait (1.0s)

Tick Interval を使う方法

Tick 自体の呼び出し間隔を間引きたい場合は Tick Interval を設定:

AMyActor::AMyActor()
{
    PrimaryActorTick.bCanEverTick = true;
    PrimaryActorTick.TickInterval = 0.5f;  // 0.5 秒ごとに Tick
}
// → Tick が 2 fps 相当で呼ばれる
// Set Timer ほど厳密ではないが、シンプル

Pause 中のタイマー

Set Game Paused が true のとき、既定で Timer は止まります。Pause 中も動かしたい場合:

// C++
FTimerHandle Handle;
FTimerManagerTimerParameters Params;
Params.bMaxOncePerFrame = false;
// 残念ながら Pause 無視のフラグは無い。
// 代わりに RealTimeSeconds 基準のループを Tick 内に作る、
// または TickEvenWhenPaused = true な Actor のコンポーネントから呼ぶ。

変動間隔: Initial Start Delay Variance

複数の AI が同時に Timer 発火するとフレーム落ちの原因に。Variance を入れるとタイミングをばらせます:

Set Timer by Event
  Time                       = 1.0
  Initial Start Delay        = 0
  Initial Start Delay Variance = 0.5
  → 0 〜 0.5 秒のランダムオフセットで開始
  → 100 体の敵が一斉に攻撃せずバラバラに

よくあるトラブル

症状原因対処
Timer が呼ばれないActor が Destroy された / Begin Play 前Begin Play 後で Set
呼ばれ続けて止められないHandle を変数保存していないSet Timer の戻り値を必ず保存
関数名が違うとログby Function Name でリネームしたby Event に切替
Pause 中も動かしたい仕様で停止RealTime ベースで自作 or TickEvenWhenPaused Actor から
2 回 Set してダブル発火同じ Handle を上書きしてない事前に Is Timer Active で確認

FAQ

Q: Timer Handle を複数管理したい
A: 用途ごとに別変数の FTimerHandle を持つ。配列にして TArray<FTimerHandle> で大量管理も可能。

Q: 0.05 秒未満の細かい間隔で実行したい
A: フレーム単位なので、その用途は Tick の方が確実。Set Timer は最小でも 1 フレーム間隔(約 0.016 秒以上)が現実的。

Q: シーン遷移しても Timer が残る?
A: 残りません。新しい World が作られて TimerManager もリセットされます。グローバルなタイマーが欲しい場合は GameInstance に持たせる必要があります。

Q: 動的に時間を変えたい (例: 加速していく敵 AI)
A: Clear Timer して新しい Time で Set Timer し直す。または再帰的に SetTimer を呼ぶ自前ループ。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 床の上に乗ったらイベントを発生させる方法
  2. OverlapAllDynamicとOverlapAllの違い
  3. タイトル画面を作る方法
  4. サードパーソンテンプレートでのキャラクター表示の仕組みと非表示にする方法
  5. ボタンに文字を記載する方法
  6. Event ActorBeginOverlapとOn Component Begin Overlapの違い
  7. キャラクターに特定のオブジェクトとの当たり判定を付ける
  8. 特定のオブジェクトに触れたとき、キャラクターが倒れるようにする
  9. 動いているオブジェクトに静止しているキャラクターが当たり判定を持たない原因と解決方法
  10. 「On Component Hit」に「Cast To ~」で複数のクラスを指定する方法
  11. Blenderファイルをインポートする方法
  12. 鏡を作成する方法
  13. レベルブループリントでキャラクターの出現を設定する方法
  14. サードパーソンテンプレートにおけるキャラクター出現の定義
  15. アイテムに近づいたらボタンを押してイベントを発火させる方法
  16. 画面の中央にメッセージを表示する方法
  17. どこからでも呼び出せるカスタムイベントを作成する方法
  18. カスタムイベントに引数を追加する方法
  19. 「Get Overlapping Actors」から特定のクラスの場合のみ処理を実行する方法
  20. オブジェクトに近づいている間だけメッセージを表示する方法
  21. PCの画面を操作するUIを作る方法
  22. コンテンツブラウザに画像を追加する方法
  23. SetInputMode_UIOnlyを取り消す方法
  24. 特定の画像の上にマウスカーソルを置いたら手マークにする方法
  25. オブジェクトがアウトライナーで選択できない原因と解決策
  26. PlayerStartを作成する方法
  27. メニュー画面を作成して開く方法
  28. 「Esc」キーを押してメニュー画面を開く方法
  29. イベントの「On Clicked」と「On Pressed」の違い
  30. 「Set Input Mode」の種類と使い方
  31. 「Set Game Paused」の使い方と詳細解説
  32. Motion Matchingとは?
  33. 「GameMode」と「GameModeBase」の違い
  34. マップに配置したTargetPointを取得する方法
  35. TargetPointにタグをつけて取得する方法
  36. Spawnしたインスタンスがイベントを実行する方法
  37. 特定の時間ごとに処理を実行する方法
  38. 数値をランダムで出力する方法
  39. ThirdPersonテンプレートでキャラクターの移動を歩くように変更する方法
  40. MaxWalkSpeedを変更する方法
  41. しゃがむ動作を導入する方法
  42. キャラクターのアニメーションを設定する方法
  43. 導入済みのプラグインを確認する方法
  44. Motion Matchingの導入と必要なプラグイン
  45. プレイヤーを非表示にする方法
  46. カメラを傾ける角度を制限させる方法
  47. 配列からランダムに重ならない要素を特定の数取得する方法
  48. カメラの映す画面に文字やエフェクトを付ける方法
  49. キャラクターやメッシュを非表示にした際にカメラが移動しなくなる問題の解決方法
  50. プライマリーデータアセットを活用する方法
  51. プレイヤーのHPといった変数を定義する最適な場所
  52. カメラに映った画面をスクリーンショットとして保存する方法
  53. ゲーム内のカメラ映像を保存して再表示する方法
  54. HighResShot を使って高解像度の画像を保存する方法(UE5)
  55. HighResShotで保存した画像のファイル名を取得する方法
  56. SceneCapture2DとFrameGrabberの画像保存方法の比較
  57. SceneCapture2Dを使用して画像を保存・取得する方法
  58. HighResShotとTake High Res Screenshotの違い
  59. ゲーム終了ボタンを作成する方法
  60. 「Save Game To Slot」の戻り値がfalseになる問題の解決方法
  61. 画面上にメッセージを指定された時間表示させる方法
  62. シェーダコンパイル時間を短縮する方法
  63. 「Take High Res Screenshot」実行時に「シェーダをコンパイル」に長時間待たされる問題とその解決策
  64. データベースを活用する方法
  65. UE5.5がインストールされた環境にUE5.4を追加で導入する方法
  66. World PartitionとWorld Compositionの違い
  67. オープンワールドテンプレートとは?
  68. ポーンをスポーンさせても視点を切り替えない方法
  69. キャラクター同士がすり抜けてしまう問題の解決方法
  70. キャラクターの外見を動的に変更
  71. World Partitionでインスタンスが「アンロード済み」になる問題
  72. データ アセットとデータ テーブルの違い
  73. コンポーネントイベントグラフ内で親クラスの変数にアクセスする方
  74. エディターのソースコードの自動保存の頻度を高める方法
  75. SpawnActorでSpawn Transform Rotationが反映されない理由
  76. ミニマップを表示しポーンの位置を反映する方法
  77. RInterp ToとVInterp Toの違い
  78. 毎秒実行するイベントの定義方法
  79. Niagara のエフェクトにコリジョンを持たせる方法
  80. 「Overlap」と「Hit」の違い
  81. OverlapはあるがHitがない原因
  82. Overlapした位置の座標を取得する方法
  83. ブループリントでレベル間のパラメータを受け渡す方法

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