WisdomSoft - for your serial experiences.

時間

ゲームが起動してから現在のフレームが描画されるまでの時間を取得することで、フレームの更新速度に依存しない時間によるアニメーション処理が可能になります。

ゲーム時間の管理

Update() メソッドが連続して呼び出されることが理解できれば、このメソッドの中にフレームごとのデータ更新処理を記述し、オブジェクトやゲームの進行を管理できるようになります。キャラクターの移動、弾道計算、AI、その他の多くの処理を Update() メソッドのタイミングで実行することになります。

フレーム単位の処理によるアニメーションは、フレームレートへの依存に注意する必要があります。環境によって、またはパフォーマンスによって、1 秒間に生成されるフレーム数は変わります。もし 1 秒間に 30 フレームの更新を前提としたアニメーションを作成した場合、高性能なコンピュータ環境で 1 秒間に 60 フレームで実行されると倍の速さになってしまいます。

アニメーションなど、フレーム数ではなく時間によって制御したい更新処理を行うには、ゲーム時間を取得しなければなりません。ゲーム時間は、ゲーム起動後から現在までの時間など、ゲームの進行に従って経過する時間情報を提供します。

ゲーム時間を取得するには UnityEngine.Time クラスを使います。

UnityEngine.Time クラス
public sealed class Time

ゲームが起動してから、現在のフレームまでの経過時間は time プロパティから取得できます。

Time クラス time プロパティ
public static float time { get; }

このプロパティはゲーム起動時からの経過時間を秒単位で表す浮動小数点数を返します。

逆に、時間ではなくフレーム数でゲームの進行を管理したい場合、現在までの総フレーム数を frameCount プロパティから取得できます。

Time クラス frameCount プロパティ
public static int frameCount { get; }

例えば、1 秒間に 30 フレームという固定レートでゲームが実行されている場合、総フレーム数が 300 であれば 10 秒経過していると予測できます。フレーム数の設定や固定レートについては後述します。

コード1
using UnityEngine;

public class Test : MonoBehaviour 
{
	void Update() 
	{
		if (Time.frameCount % 60 == 0)
		{
			print("Time=" + Time.time);
		}
	}
}
実行結果
コード1 実行結果

コード1は 60 フレーム間隔で現在のゲーム時間をコンソールに出力するスクリプトです。一定間隔で print() メソッドを呼び出すために、frameCount プロパティから得られる現在の総フレーム数に対して 60 で割った余りを求め、その結果が 0 であれば、すなわち 60 の倍数であれば 60 フレームが経過したと判定しています。

フレーム数ではなく時間経過でオブジェクトを制御する場合、もっとも便利で利用される機能が deltaTime プロパティです。

Time クラス deltaTime プロパティ
public static float deltaTime { get; }

このプロパティは、直前のフレーム更新から、現在のフレームまでの経過時間を秒単位の浮動小数点数で返します。

例えば 1 秒間に 60 フレーム固定のゲームであれば、このプロパティは常に 0.016 に近い数を返すでしょう。当然、フレームの更新処理に費やした時間によって変動します。

コード2
using UnityEngine;

public class Test : MonoBehaviour 
{
	void Update() 
	{
		float yr = 20 * Time.deltaTime;
		transform.Rotate(0, yr, 0);
	}
}
コード2 実行結果
コード2 実行結果

コード2は 1 秒間に Y 軸に対して 20 度回転させるスクリプトです。このように、移動量や回転量に deltaTime プロパティの結果を掛けると、1 秒間で指定した値に到達するために必要な、現在のフレームで加えるべき値を計算できます。

Time クラスの機能を用いることで、このように時間経過に対して一定のデータ更新を行うことができるようになります。