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メソッド内での処理が多ければそれだけ処理負荷がかかります。

ここら辺は

Update 関数を使用すると、定期的にスクリプトからの入力やその他のイベントをモニターして、適切な処置を取ることができます。たとえば、“forward” キーが押された場合、キャラクターを動かすかもしれません。このような時系列のアクションを取り扱う場合、ゲームのフレームレートおよびアップデート...

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のスクリプトリファレンスに記述されていますが、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内で記述した方がいいってことですね。

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

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

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

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

スポンサーリンク

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

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