【Unity】端末の性能差によってスピードが変わる問題。スマホやPCでも同速度にする方法

【Unity】端末の性能差によってスピードが変わる問題。スマホやPCでも同速度にする方法

 UnityのスクリプトでUpdate()内の処理が端末によって安定しないことがありますよね。同期処理や点数の加算、技や攻撃の発動間隔などなど。それはフレームレート(FPS)の問題です。今回はどの端末でも同じ性能を維持できるように問題を解決していきます。

なぜこのような問題が起きるのか?

 結論から言うと、Unityのフレームレートは一定ではないから

 Update()では、その端末ができる最高速度で処理を行います。

 なので、以下のコードのように攻撃の間隔をフレームレートに依存して決めてしまうと端末によって間隔が変わる問題が起きるわけですね。

int i = 0;

void Update(){
  i++;
  if(i>=5){
    //5フレーム毎に攻撃処理
    Attack();
    i=0;
  }
}

Time.deltaTimeを使う

 この Time.deltaTime は、現在のフレームと前のフレームの間の時間を保持します。フレーム間の時間なので、端末の性能が高くても低くても、Update()内の処理は変わりません。

(翻訳)

最後のフレームからの完了時間(秒単位)(読み取り専用)。

このプロパティは、現在のフレームと前のフレームの間の時間を提供します。

Time.deltaTimeを使用して、ゲームオブジェクトをy方向にn単位/秒で移動します。 nにTime.deltaTimeを掛けて、yコンポーネントに追加します。

MonoBehaviour.FixedUpdateは、deltaTimeの代わりにfixedDeltaTimeを使用します。 MonoBehaviour.OnGUI内のTime.deltaTimeに依存しないでください。 Unityは、フレームごとに複数回OnGUIを呼び出すことができます。 アプリケーションは、呼び出しごとに同じdeltaTime値を使用します。

次の例では、タイマーを実装しています。 タイマーは、フレームごとにdeltaTimeを追加します。 この例では、タイマー値をアナウンスし、2秒に達するとゼロにリセットします。 MonoBehaviour.UpdateがdeltaTimeを追加するとき、タイマーは2.0に達しません。 テストは、タイマーが2秒移動するためのものです。 スクリプトコードは報告された時間を削除し、タイマーが再起動します。 再起動は必ずしも正確に0.0であるとは限りません。 速度は0.5秒から2.0秒の間で変化します。 Time.timeScaleは、選択した経過時間スケールを格納します。

(原文)

The completion time in seconds since the last frame (Read Only).

This property provides the time between the current and previous frame.

Use Time.deltaTime to move a GameObject in the y direction, at n units per second. Multiply n by Time.deltaTime and add to the y component.

MonoBehaviour.FixedUpdate uses fixedDeltaTime instead of deltaTime. Do not rely on Time.deltaTime inside MonoBehaviour.OnGUI. Unity can call OnGUI multiple times per frame. The application use the same deltaTime value per call.

The following example implements a timer. The timer adds deltaTime each frame. The example announces the timer value and resets it to zero when it reaches 2 seconds. The timer does not hit 2.0 when MonoBehaviour.Update adds deltaTime. The test is for the timer moving 2 seconds. The script code removes the reported time, and the timer restarts. The restart is not always exactly 0.0. The

https://docs.unity3d.com/jp/current/ScriptReference/Time-deltaTime.html

 Time.deltaTimeを使ってコードを書いてみます。

10秒ごとに処理を行うソースコード

float time = 0f;

void Update(){
  time+=Time.deltaTime;
  if(time>=10f){
    //10秒ごとに行いたい処理
    time = 0f;
  }
}

 これでスマホやPCでスピードが変わったりしませんね。

まとめ

 Update()内で加算減算処理を行う時は注意が必要。

 フレームレートは一定ではない。

  Time.deltaTime を使ってフレーム間の秒数を計算すれば、端末の性能に影響されないで処理可能。

 厳密に時間処理を行うならコールルーチンやUniRxを使うのが良い。