結論から先に書く
Time.deltaTimeの正式な意味
現在のフレームと直前のフレームとの間の時間を秒で返す
読み取り専用で代入はできない
なぜキャラの移動に使うか?
フレーム間に要する時間が変動してもキャラの移動速度を一定に保つことが出来るから
結論に至るまで
最初にUnityで次のようなC#スクリプトを見た時、Time.deltaTimeの意味が全く分からなかった。
// 移動ベクトル
Vector3 MOVEX = new Vector3(3.0f, 0.0f, 0.0f);
// Update is called once per frame
void Update()
{
// 十字キーでオブジェクトを操作する
if (Input.GetKey(KeyCode.RightArrow)) // 右矢印キー
{
transform.position += MOVEX * Time.deltaTime;
}
:
:
}
十字キーでキャラクタを動かすというスクリプトだった。
transform.positionは、キャラクタの現在位置。
MOVEXは、Vector3型で定義しているからX方向への移動量だとなんとなく分かった。
では、MOVEXに掛けているTime.deltaTimeとは一体何だ???
いままでTime.deltaTimeをC言語の#includeみたいなおまじないみたいなものだと逃げこんできた。これではいけないと思いきちんと調べてみた。
Unity公式ドキュメントにきちんと(英語だが)書いてある。
該当部分の英語
This property provides the time between the current and previous frame.
between ~ and は中学で習った。
でもGoogle翻訳の力を借りた。Time.deltaTimeの意味はこうなる。
現在のフレームと直前のフレームとの間の時間を提供します
時間の単位は、その直前にこう書いてあった。
The completion time in seconds since the last frame (Read Only).
意味
最後のフレームからの完了時間(秒単位)(読み取り専用)
Google翻訳
Time.deltaTimeをまとめるとこうなる。
現在のフレームと直前のフレームとの間の時間を秒で返す。
読み取り専用で代入はできない。
先ほどのスクリプトに当てはめて考えてみる。
Updateメソッドは、フレーム毎の処理。
1秒間に60フレーム処理していたとすると、Updateメソッド内の処理は、1秒間に60回実行される。
もし、キーボードの右矢印キーを押しっぱなしの状態だと、
transform.position += MOVEX * Time.deltaTime;
の部分が1秒間に60回実行されることになる。
もし、Time.deltaTimeを使わずに
transform.position += MOVEX;
などとしてしまったら、どうなるか?
1フレームに要する時間はコンピュータの場合一定ではない。
さっきまで60フレームで動作していたのに、ちょっと処理が重くなってきたので30フレームで動作しているなんてことがある。
となるといくらベクトルで移動量を数値指定しても、コンピュータの状況によってキャラの移動速度が変化してしまうことになる。
プログラムが変わらないのにコンピュータの状態によってキャラの移動速度が変わるなんて変だ。
そこでTime.deltaTimeの出番である。
transform.position += MOVEX * Time.deltaTime;
移動量にTime.deltaTimeを掛け合わせることで、フレーム間に要する時間が変動してもキャラの移動速度を一定に保つことが出来る。
上記の式なら、もし60フレームで動作している場合だとTime.deltaTimeの値は、約1/60秒くらいになる。その時は、約0.016…を移動量に掛け合わせることになる。
当然移動量は、
transform.position += MOVEX;
の式と比べて少なくなるわけだが、フレーム間に要する時間の変動に対応できる。
transform.position += MOVEX * Time.deltaTime;
とすれば、移動ベクトルの数値
Vector3 MOVEX = new Vector3(3.0f, 0.0f, 0.0f);
を変化させるだけでキャラの移動速度を変更できるのだ。
…理解に時間が掛かった。
自分ってアホだったんだとつくづく思った。
コメント