この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:T
更新日時:2026-06-11 07:07:02

タイトル: 特定の時間ごとに処理を実行する方法
SEOタイトル: Unreal Engine タイマー処理 (Set Timer) 完全ガイド(Looping / Function / Event / 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 で大量管理も可能。

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 を呼ぶ自前ループ。