Skip to content

TimerFrame

1. 概要

TimerFrame は、指定したフレーム数が経過した後に Unit を発行するファクトリメソッドです。

dueTimeFrame だけを指定する overload は、指定フレーム数が経過した時点で Unit を 1 つ発行し、その直後に完了します。periodFrame も指定する overload は、初回発行後も一定フレーム間隔で Unit を発行し続け、自動的には完了しません。

Timer のフレームベース版であり、Unity などゲームエンジン上でフレーム単位のタイミング制御が必要な場合に使用します。FrameProvider を指定する overload では、フレームを数える基準を差し替えられます。Unity では UnityFrameProvider.UpdateUnityFrameProvider.FixedUpdateUnityFrameProvider.PostLateUpdate などを指定して、PlayerLoop タイミングを選べます。利用できる Unity 向け Provider は Unity providers を参照してください。

2. シグネチャ

指定フレーム後に 1 回だけ発行する

csharp
public static Observable<Unit> TimerFrame(int dueTimeFrame, CancellationToken cancellationToken = default)
public static Observable<Unit> TimerFrame(int dueTimeFrame, FrameProvider frameProvider, CancellationToken cancellationToken = default)

dueTimeFrame に指定したフレーム数が経過した時点で Unit を 1 つ発行し、完了します。FrameProvider 指定版では、既定の ObservableSystem.DefaultFrameProvider ではなく、指定した FrameProvider のフレーム進行を使用します。

csharp
Observable.TimerFrame(60)
Observable.TimerFrame(60, UnityFrameProvider.FixedUpdate)

TimerFrame 単発のマーブルダイアグラム

この例では、dueTimeFrame フレームが経過したタイミングで Unit を 1 つ発行し、直後に完了します。

初回遅延後に一定フレーム間隔で繰り返す

csharp
public static Observable<Unit> TimerFrame(int dueTimeFrame, int periodFrame, CancellationToken cancellationToken = default)
public static Observable<Unit> TimerFrame(int dueTimeFrame, int periodFrame, FrameProvider frameProvider, CancellationToken cancellationToken = default)

dueTimeFrame で初回発行までのフレーム数を指定し、その後は periodFrame フレームごとに Unit を発行し続けます。自動的には完了しないため、CancellationToken、購読解除、または Take などで停止条件を与えます。

csharp
Observable.TimerFrame(30, 10)
Observable.TimerFrame(30, 10, UnityFrameProvider.FixedUpdate)

TimerFrame 繰り返しのマーブルダイアグラム

この例では、dueTimeFrame フレーム後に最初の Unit を発行し、その後は periodFrame フレームごとに Unit を発行し続けます。

overload の使い分け

overload使う場面
TimerFrame(int)指定フレーム後に 1 回だけ発行する
TimerFrame(int, int)初回遅延と周期を分けて、一定フレーム間隔で繰り返す
FrameProvider 付きテスト容易性の確保、Unity の PlayerLoop タイミング指定、カスタム FrameProvider の利用

3. サンプルコード

csharp
using R3;

// 60 フレーム後に 1 回だけ発行して完了
Observable.TimerFrame(60)
    .Subscribe(
        _ => Console.WriteLine("発火"),
        _ => Console.WriteLine("完了"));
csharp
using R3;

// 30 フレーム後に初回発行、以降 10 フレームごとに繰り返し
var cts = new CancellationTokenSource();

Observable.TimerFrame(30, 10, cts.Token)
    .Subscribe(_ => Console.WriteLine("tick"));

// cts.Cancel() で停止
csharp
using R3;

// Unity では PlayerLoop タイミングを指定できる
Observable.TimerFrame(1, UnityFrameProvider.FixedUpdate)
    .Subscribe(_ => UnityEngine.Debug.Log("FixedUpdate 基準で 1 フレーム後"));

4. 補足

Timer との違い

TimerTimeSpan / DateTimeOffset による実時間ベースの遅延・繰り返しを行います。TimerFrame はフレーム数ベースです。フレームの概念がある環境では TimerFrame が自然な選択になります。

IntervalFrame との違い

IntervalFrame は初回の発行も periodFrame 後に行われます。IntervalFrame(periodFrame)TimerFrame(periodFrame, periodFrame) と同じ用途で使えます。初回遅延と周期を別々に指定したい場合は TimerFrame を使用してください。