時間
ゲーム時間の管理
Update() メソッドが連続して呼び出されることが理解できれば、このメソッドの中にフレームごとのデータ更新処理を記述し、オブジェクトやゲームの進行を管理できるようになります。キャラクターの移動、弾道計算、AI、その他の多くの処理を Update() メソッドのタイミングで実行することになります。
フレーム単位の処理によるアニメーションは、フレームレートへの依存に注意する必要があります。環境によって、またはパフォーマンスによって、1 秒間に生成されるフレーム数は変わります。もし 1 秒間に 30 フレームの更新を前提としたアニメーションを作成した場合、高性能なコンピュータ環境で 1 秒間に 60 フレームで実行されると倍の速さになってしまいます。
アニメーションなど、フレーム数ではなく時間によって制御したい更新処理を行うには、ゲーム時間を取得しなければなりません。ゲーム時間は、ゲーム起動後から現在までの時間など、ゲームの進行に従って経過する時間情報を提供します。
ゲーム時間を取得するには UnityEngine.Time クラスを使います。
public sealed class Time
ゲームが起動してから、現在のフレームまでの経過時間は time プロパティから取得できます。
public static float time { get; }
このプロパティはゲーム起動時からの経過時間を秒単位で表す浮動小数点数を返します。
逆に、時間ではなくフレーム数でゲームの進行を管理したい場合、現在までの総フレーム数を frameCount プロパティから取得できます。
public static int frameCount { get; }
例えば、1 秒間に 30 フレームという固定レートでゲームが実行されている場合、総フレーム数が 300 であれば 10 秒経過していると予測できます。フレーム数の設定や固定レートについては後述します。
using UnityEngine; public class Test : MonoBehaviour { void Update() { if (Time.frameCount % 60 == 0) { print("Time=" + Time.time); } } }
コード1は 60 フレーム間隔で現在のゲーム時間をコンソールに出力するスクリプトです。一定間隔で print() メソッドを呼び出すために、frameCount プロパティから得られる現在の総フレーム数に対して 60 で割った余りを求め、その結果が 0 であれば、すなわち 60 の倍数であれば 60 フレームが経過したと判定しています。
フレーム数ではなく時間経過でオブジェクトを制御する場合、もっとも便利で利用される機能が deltaTime プロパティです。
public static float deltaTime { get; }
このプロパティは、直前のフレーム更新から、現在のフレームまでの経過時間を秒単位の浮動小数点数で返します。
例えば 1 秒間に 60 フレーム固定のゲームであれば、このプロパティは常に 0.016 に近い数を返すでしょう。当然、フレームの更新処理に費やした時間によって変動します。
using UnityEngine; public class Test : MonoBehaviour { void Update() { float yr = 20 * Time.deltaTime; transform.Rotate(0, yr, 0); } }
コード2は 1 秒間に Y 軸に対して 20 度回転させるスクリプトです。このように、移動量や回転量に deltaTime プロパティの結果を掛けると、1 秒間で指定した値に到達するために必要な、現在のフレームで加えるべき値を計算できます。
Time クラスの機能を用いることで、このように時間経過に対して一定のデータ更新を行うことができるようになります。