This document is about: QUANTUM 3
SWITCH TO

Frame Timer

タイマーに基づくゲームプレイを実装する際に、QuantumのFrameTimer構造体が使用できます。例えば、スキルのクールダウン・リスポーン時間・シミュレーション中の定期的なチェックなどに使用できます。

秒数/ティック数を指定して、タイマーを開始します。

C#

FrameTimer timerA = FrameTimer.FromFrames(frame, 60)
FrameTimer timerB = FrameTimer.FromSeconds(frame, 2)
FrameTimer timerC = default(FrameTimer);

timerAtimerBは実行状態になりますが、timerCはまだ設定されていない状態です。

上記で設定したタイマーについて、FrameTimerの状態をチェックする例は次の通りです。

C#

timerA.IsRunning(frame); // returns TRUE
timerB.IsRunning(frame); // returns TRUE
timerC.IsRunning(frame); // returns FALSE

timerA.IsSet; // returns TRUE
timerB.IsSet; // returns TRUE
timerC.IsSet; // returns FALSE

FrameTimerは目標フレームを保持し、タイマーが停止した瞬間を問い合わせることができます。また、経過時間や残り時間を返すことができるので、例えばゲームUIに表示するのにも便利です。

C#

if (timer.HasStoppedThisFrame(frame)) {
    // ちょうどタイマーが停止したフレームでのみ実行される
}
else {
    var ticksRemaining = timer.RemainingFrames(frame);
    var secondsRemaining = timer.RemainingSeconds(frame);

    var ticksElapsed = timer.ElapsedFrames(frame);
    var elapsedSeconds = timer.ElapsedSeconds(frame);
}

以下の例のように、FrameTimerは、DSLからコンポーネントに追加したり、フレームのグローバル変数に追加したりすることができます。

Qtn

component Character {
    FrameTimer SkillCooldown;
}

global {
    FrameTimer GameTimer;
}

次の例では、コンポーネントのFrameTimerを使用してスキルのクールダウンを管理しています。グローバル変数のFrameTimerでも同じロジックが適用できます。

C#

namespace Quantum
{
  using Photon.Deterministic;
  using UnityEngine.Scripting;
  
  [Preserve]
  public unsafe class CharacterSystem : SystemMainThreadFilter<CharacterSystem.Filter> {
    public struct Filter {
      public EntityRef Entity;
      public Character* Character;
    }

    public override void Update(Frame frame, ref Filter filter)
        var character = filter.Character;
        if (character->SkillCooldown.IsRunning(frame) == false) {
            // スキルを実行し、クールダウンをリセットする

            // 新しいタイマーを作成して、クールダウンをリセットする
            character->SkillCooldown = FrameTimer.FromSeconds(frame, 2);

            // タイマーをリスタートして、クールダウンをリセットする
            // ただし、タイマーは以前に設定されている(例:コンポーネントに追加する際)必要があります
            character->SkillCooldown.Restart(frame);
        }
    }
}
Back to top