2015年04月21日

Time.deltaTimeを使う


さて、Unityをいじり始めてそろそろ半年が経とうかというところです。
やりはじめの頃、大切さに気付かなかった、ある処理方法があります。
そして、その大切さにやっと最近気づいた愚か者なおれです(;・∀・)

以下が、その参考ソース。
Unity歴の長い人や、察しのいい方などは、すぐ問題点に気づけると思います。

private GameObject Human;                   //ヒューマンオブジェクト

略…

void Update(){
  //Humanオブジェクトを右に動かす
  MoveRight();

}

//Humanを右に1ずつ動かすメソッド
void MoveRight(){

  Vector3 humanGrid;                        //Humanの座標
  humanGrid=Human.transform.localPosition;	//Humanの座標取得
  humanGrid.x=humanGrid.x+1;                //アップデートの度に右に1動く
  Human.transform.localPosition=humanGrid;  

}

こんな感じ。
おれは察しが悪いので、実際に動かしてみるまで問題点に気付きませんでした。
参考にしたサイトの説明をちゃんと読んでいるにもかかわらず、です(;・∀・)

さて何がダメちんなのかと言うとですね。
たとえばこのアプリを少し型の古いデバイスで動かした場合、
Humanが右に動くスピードが遅くなります。いわゆる処理落ち。

Update関数は、稼働中は毎フレームごとに呼び出されます。
通常、特に指定してない限り秒間に呼び出されるフレーム数は、
60フレームです。俗にいう60fps。

比較的新しい端末であればまったく問題ないのですが、
古い端末で動かした場合、マシンパワーが足りなくて、
一秒間に読み込めるフレーム数が60に足りない場合もあります。
半分の30フレームだったり、もっと少なかったり…
逆に気合の入ったマシンで一秒間に120フレーム読み込むマシンてのも、あるかもしれません。

で上記コードだと、一秒間にどれだけ読み込むフレーム数が少なくても、
毎フレームでHumanが右に動く距離は1m(単位がないと厳しいので、仮にメートルにします)。
つまり、60フレーム読み込めていれば、1×60で、一秒間に動く距離は60m、
30フレームしか読み込めてない場合は、1×30で、一秒間に動く距離は30m。
120フレーム読み込める場合は、1×120で、一秒間に動く距離は120m。
こんな感じで、Humanの移動距離がマシンパワーや処理速度に依存してしまうのです。
古い端末だと、処理落ち的なもっさりした挙動になってしまうのですよ。

そこで効果を発揮するのが、こちら。

Time.deltaTime

このTime.deltaTimeてのは、
前のフレームの処理を読み込んでから次のフレームを読み込むのにかかった時間です。
単位は秒。これを使ってあげると、うまい具合に移動距離を揃えてあげることが出来ます。

上記の例で言えば…

humanGrid.x=humanGrid.x+1;

この部分を…

humanGrid.x=humanGrid.x+(60*Time.deltaTime);

こんな感じに変更してあげます。
こうしてあげると、フレーム数はどうあれHumanは一秒間に右に60m進む計算です。
具体的な例をあげて計算してみると、こんな感じ。

60fpsの場合→(60×(1/60)秒)×60回=一秒間に進んだ距離60m
30fpsの場合→(60×(1/30)秒)×30回=一秒間に進んだ距離60m
120fpsの場合→(60×(1/120)秒)×120回=一秒間に進んだ距離60m

こんな感じです。各式の(1/60)秒、(1/30)秒、(1/120)秒の部分が、
Time.deltaTimeですね。
これで、fpsがいくつであろうが、Humanは1秒で右に60m進みます。
もちろん、処理中にfpsが変動しても問題なし。
どれだけfpsが変動しようが、一秒間で60m進みます。

しかしなんつーか…
これぐらいのことが予想できないなんて…おれも修行が足りませんよね…(;・∀・)

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)