UnityのUpdateとFixedUpdate、LateUpdate関数について

今回はUnityで当たり前のように使っているUpdate関数、FixedUpdate関数、LateUpdate関数についてみていこうと思います。

これらの関数はMonoBehaviourクラスを継承して作成したクラスで呼ばれるようになります。

UnityでC#のファイルを作成した時にデフォルトでMonoBehaviourクラスを継承して新しいクラスが作成されていると思います。

例えばC#でTestClassというファイルを作成したら

のようにMonoBehaviourを継承してTestClassが作成され、StartとUpdate関数がデフォルトで用意されています。

FixedUpdateやLateUpdateも記述すれば呼ばれるようになります。

JavaScriptで新しいファイルを作成した場合は明示的に表示されていませんがMonobehaviourクラスを継承して作成されています。

ちなみにこのMonobehaviourクラスを継承して作られたクラスはインスタンス化は出来ません。

スポンサーリンク

Update関数

ゲームで何らかの処理をしようと思ったらUpdate関数内に記述する事が多いと思います。

Update関数は毎フレーム呼ばれるので、キーボードを押したか?指定した時間が経過したか?目的地についたかどうか?

等を判断する時に便利です。

Update関数が呼ばれるタイミングはアニメーションがレンダリング(画像の生成等)される前に呼ばれます。

なのでUpdateでキャラクターの位置等を変更し、その後キャラクター等のレンダリングが行われるという感じになります。

Time.deltaTime

Update関数はコンピューターの性能によって呼ばれる回数が変わってくるためキャラクターの移動をさせる時等は性能差を考慮したスクリプトにする必要があります。

その為に使用するのがTime.deltaTimeです。

このTime.deltaTimeは最後のフレームを終了するのに要した時間をあらわします。

最後のフレームを終了するのに要した時間って何!?となりそうですが・・・・(^_^;)

つまりは前回のUpdateから今のUpdateが呼び出されるまでの時間ということですね。

その為

↑のようにスクリプトを作成し、何らかのゲームオブジェクトに設定すればこのゲームオブジェクトが登場してからの経過時間を調べる事が出来ます。

経過時間計測結果

↑が実行例です。

Update関数内でキャラクターの移動をさせる処理を記述する事が多いと思いますが、性能差を考えこのTime.deltaTimeを移動値にかけて利用するようにします。

基礎的なキャラクターの移動に関しては

Unityで3Dキャラクターモデルを配置し、キャラクターをCharacterControllerの機能を使って移動させるようなプログラミングをしてみます。

を参照してください。

LateUpdate関数

LateUpdate関数はUpdate関数が呼ばれた後に実行される関数で中身としてはUpdateと同じです。

用途としてはキャラクターが移動した後にカメラをキャラクターに追従させる時等に使用します。

Update関数内でキャラクターの移動とカメラの追従を同時に行おうとするとうまくカメラが追従してくれない事があります。

そこで、Update関数でキャラクターの移動をさせてレンダリングした後にLateUpdate関数でカメラがキャラクターを追従するようにするとうまく出来たりします。

Update関数で何らかの処理をした後に実行したいものがあるならばLateUpdate関数を利用するといいですね。

LateUpdate関数に関しては他に書く事ないなぁ・・・・(^_^;)

実際に使っている記事は

Unityのゲームで使用するキャラクターの移動やカメラの回転、カメラのズーム機能、カメラの壁対策、人との会話、敵を攻撃等のすべてをマウス操作で行う為の機能を作成していきます。

やブログの右上にある『サイト内検索が出来ます』でLateUpdateで検索して頂くといくつかの例が出てきますので参照してください。

FixedUpdate関数

FixedUpdate関数はUpdate関数と似ていますが、Update関数はゲームオブジェクト等の動作のレンダリング前で、

FixedUpdate関数は物理挙動の更新の直前に呼ばれます。

Update関数はコンピュータの性能差で呼ばれる回数が変わりますが、FixedUpdate関数は固定フレームレート(1秒間に呼ばれる回数が同じ)で呼ばれます。

フレームレートは1秒間に呼ばれるフレームの回数なのでfps(フレームパーセカンド)で表現します。

1秒間に30回フレームが呼ばれるとしたら30fpsという事ですね。

このフレームレートはUnityメニューのEdit→Project Settings→Timeで設定出来ます。

FixedTimeStepの設定

↑のようにTimeを選択します。

TimeManagerのインスペクタ

↑のようにインスペクタにTimeManagerが表示され、Fixed TimeStepでフレームレートを変更出来ます。

デフォルトで0.02となっていて0.02秒間に1回フレームが呼ばれる設定になっています。

つまり1フレーム/0.02秒ですね、これを1秒間に直していくと100フレーム/2秒→50フレーム/1秒、つまり50fpsという事になります。

よってFixedUpdate関数はデフォルトの設定で1秒間に50回呼び出されると言う事になります。

Fixed TimeStepを変更すれば固定フレームレートを変更出来るのでここを1にすれば1秒毎にFixedUpdate関数が呼ばれるようになります。

もっと多くFixedUpdate関数が呼ばれるように小さい値を設定する事も出来ますが、FixedUpdate関数内での処理が多ければそれだけ処理負荷がかかります。

ここら辺は

Unity のマニュアルは、Unityの使い方を学ぶ手助けとなります。Unityを使って 2D や 3D ゲームを作成したり、ゲーム以外のアプリを作成したりして多くの経験を積みましょう。

Unity公式のタイムとフレームレートの管理のページをご覧ください。

Rigidbodyを使ってゲームオブジェクトに力を加える時はUpdate関数ではなくFixedUpdate関数で行うのがいいとチラホラ見た事があるんですが、

その理由はFixedUpdate関数の呼ばれるタイミングが物理挙動の更新の直前に呼ばれる、固定フレームレートで呼ばれるというのがあるんですね。

Update関数とFixedUpdate関数のテスト

Update関数とFixedUpdate関数を見てきたので実際にテストして確認してみましょう。

両方の関数内でフレームレートを計算してコンソールに表示してみます。

Update関数内でUpdate関数が呼ばれた回数を計算した秒数で割ってfpsを表示しています。

FixedUpdate関数内ではTime.fixedDeltaTimeとTime.deltaTimeを使用して秒数を計算しています。

FixedUpdate関数内でTime.deltaTimeを呼び出すと固定フレームレートの値が返されるようなのでその為の実験です。

固定フレームレートの値という事はTime.fixedDeltaTimeの値が返されるという事でしょうか。

今回はTimeManagerのFixed TimeStepを0.02のまま使用します。

それではこのスクリプトを何らかのゲームオブジェクトに設定しUnityを実行してみましょう。

UpdateとFixedUpdateのテスト1

↑が実行最初の結果です。

FixedUpdateは50fpsで呼ばれているのがわかりますね。

Updateも50fpsになってます。

UpdateとFixedUpdateのテスト2

↑がしばらく実行した後の結果です。

FixedUpdateではほぼ50fps、Updateでは60近くになっています。

Update関数は毎フレーム実行されるのでこういう風になりますね。

ゲームのフレームレートはスタンドアロン(パソコンの実行形式)では最大達成可能フレームレート、スマフォ等のモバイル出力された場合は最大達成可能フレームレートより小さくなっています。

このフレームレートはスクリプトから設定する事が可能です。

先ほどのスクリプトにも記述していていましたが、Application.targetFrameRateに値を入れる事で変更する事が可能です。

ここらのフレームレートに関しては

Unity のマニュアルは、Unityの使い方を学ぶ手助けとなります。Unityを使って 2D や 3D ゲームを作成したり、ゲーム以外のアプリを作成したりして多くの経験を積みましょう。

Unityのスクリプトリファレンスに記述されていますが、Quality Settingsの設定によっては無視されます。

QualitySettingsを開く

↑のようにUnityメニューのEdit→Project Settings→Qualityを選択します。

QualitySettingsのインスペクタ

Quality SettingsのインスペクタでV Sync CountがDon’t Syncの時はスクリプトで設定されたフレームレートが適用されます。

それ以外の場合は無視されると言う事ですね。

それではSync Countの設定をDon’t Syncにして確認してみましょう。

フレームレートを変更した実験

スクリプトでフレームレートを20に設定したのでUpdateのfpsが20付近で止まっています。

終わりに

Update関数とFixedUpdate関数の違いはなんとなく理解してましたが、こうやって見ていくと呼ばれるタイミング自体が違うというのが再認識されました。

キャラクターを動かす場合CharacterControllerとRigidbody+コライダの2つのやり方がありますが、

CharacterControllerの場合はUpdateで操作、Rigidbody+コライダの場合はFixedUpdateで操作した方がいい理由がなんとなくわかりますね。

Rigidbodyの場合物理的な挙動(相手方に力を与えたり逆に力を加えられたり)を扱っているのでタイミングとしてはFixedUpdate内で記述した方がいいってことですね。

ふむふむなるほど・・・・・(-_-)

本当にわかっているかどうかはまぁ置いておいて・・・・(^_^;)

なんとなくでも違いがわかったのは良かったと思います。

ふむふむなるほど・・・・・(-_-)

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます