不定期開催の一分間Unity講座、主にUnityに初めて触れる方や、初めて間もない方向けのステップアップ講座です。
下はファイブボックス公式Youtube「Unityマニア」の「1分間Unity講座」の記事の詳細説明になります。
Unityのフレームレート依存の問題
Unityでは、Update()
関数、OnTriggerStay()
関数、OnCollisionStay()
関数などのイベント関数が毎フレーム連続で呼び出され、繰り返し処理を行います。しかし、このフレームに要する時間は常に一定ではなく、デバイスの性能や並行して動いているその他の処理によって変化します。
例えば、敵の動きをUpdate()
関数内で以下のように記述した場合:
transform.position += Vector3.right * 0.01f;
この場合、敵の動きはパソコンの性能やその時の状態によって毎回異なる動きになってしまいます。この問題を避けるためには、時間に依存した処理を行う必要があります。
今回は、この問題に対応する3つの方法をご紹介します。
1,
Application.targetFrameRate の活用
Application.targetFrameRate
を使用することで、アプリケーションの目標フレームレートを設定できます。ただし、これはフレームレートの上限を設定するもので、フレームごとの経過時間を一定にするものではありません。
void Start()
{
// 100FPSを目標とする
Application.targetFrameRate = 100;
}
これにより、理論上は100FPS(FPSはFrames Per Secondの略=1秒間当たりのフレーム数)で動作するように試みますが、実際のフレームレートはデバイスの性能や他の処理に依存するため、必ずしも設定したフレームレートで動作するとは限りません。
注意点として、Application.targetFrameRate
による目標フレームレートの指定はアプリケーション全体に適用されます。つまり、特定のオブジェクトに対してのみ適用されるのではなく、ゲーム全体のフレームレートを制御します。
FixedUpdate の活用
FixedUpdate
関数は特に物理演算や時間依存の処理に対して有効です。FixedUpdate
は一定の時間間隔で呼び出されるため、フレームレートに依存しない安定した動作を保証します。
FixedUpdate
は「Fixed Timestep」という1フレームの時間ごとに呼び出され、初期設定では0.02秒になっています。つまり、FixedUpdate
を使用すると1秒間に50回(1/0.02秒)の処理を行うことになります。
「Fixed Timestep」は以下の場所から確認、または変更することができます。
- 上部メニューの「Edit」⇒「Project Settings」
- 左ペインで「Time」を指定、右ペインで「Fixed Timestep」に表示された値を確認、または変更
Updateとの使い分け
- Update: フレームごとに呼び出され、ゲームのロジックやユーザー入力の処理に適しています。フレームレートに依存するため、フレームレートが変動する場合に動作が不安定になることがあります。
- FixedUpdate: 一定の時間間隔で呼び出され、物理演算や時間依存の処理に適しています。フレームレートの変動に影響されないため、安定した動作が保証されます。
Time.deltaTime の活用
Time.deltaTime
は1フレームの処理にかかる時間を表します。この値はパソコンや並行して作動している処理などにより常に変化します。
Time.deltaTime
を使用することでフレームごとの経過時間を考慮し、動きを一定にすることができます。これは、フレームレートが変動しても動作速度が一貫して保たれるためです。
Time.deltaTimeの活用事例
フレームレートに依存する動き(通常のUpdate)
以下のコードは、フレームごとに一定の距離(0.1単位)だけ右に動くオブジェクトを示します。
void Update()
{
transform.position += Vector3.right * 0.1f;
}
この場合、60FPSでは1秒間に6動きますが、30FPSでは1秒間に3しか動きません。結果として、フレームレートが変動するとオブジェクトの速度も変わってしまいます。
Time.deltaTimeを使用した動き
次に、Time.deltaTime
を使ったコードを見てみましょう。
void Update()
{
transform.position += Vector3.right * 2.0f * Time.deltaTime;
}
ここでは、Vector3.right * 2.0f
の速度(2 /秒)をTime.deltaTime
と掛け合わせています。こうすることで、1フレームごとの動きの量がそのフレームの経過時間に比例するようになります。
- 50FPSの場合:
Time.deltaTime
は0.020秒- 1フレームで移動する距離は
0.020 * 2.0 = 0.04
です。1秒間では50フレームなので、50 * 0.04 = 2.0
動きます。
- 100FPSの場合:
Time.deltaTime
は0.010秒です。- 1フレームで移動する距離は
0.010 * 2.0 = 0.02
です。1秒間では100フレームなので、0.02 * 100 = 2.0
動きます。
このように、Time.deltaTime
を使用することで、フレームレートが変動しても1秒間に2だけ動くことが保証されます。
それぞれの特性を理解し、プロジェクトにあった方法を選んでみてください。
ファイブボックスでは、Unityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。