Unityのイベント関数① | Update・FixedUpdate・LateUpdateの違いを初心者向けに解説
Unityでスクリプトを書いていると、かなり早い段階で登場するのが Update() です。
void Update()
{
}Unityの入門書やサンプルコードでもよく出てくるので、
「とりあえず毎回処理したいことはUpdateに書く」
というイメージを持っている方も多いと思います。
スクラッチの「ずっと」と同じような役割ですね。

ただ、Unityには Update() 以外にも、
void FixedUpdate()
{
}
void LateUpdate()
{
}という似たようなイベント関数があります。
名前は似ていますが、それぞれ呼び出されるタイミングや向いている処理が違います。
今回は、Unity初心者が混乱しやすい
Update
FixedUpdate
LateUpdate
の違いを、できるだけわかりやすく整理していきます。
イベント関数とは?
Unityには、特定の名前で関数を作っておくと、自動的に呼び出してくれる仕組みがあります。
たとえば、次のように Update() を書いておくと、Unityが毎フレーム自動的に呼び出してくれます。
void Update()
{
Debug.Log("Updateが呼ばれました");
}このような関数を、Unityではイベント関数と呼びます。
自分で
Update();と呼び出しているわけではありません。
決まったタイミングでUnity側が自動的に実行してくれる関数です。
Updateとは?
Update() は、Unityで最もよく使われるイベント関数のひとつです。
void Update()
{
}Update() は、基本的に1フレームに1回呼び出されます。
ゲーム画面が更新されるたびに呼び出される場所、と考えるとわかりやすいです。
Updateに向いている処理
Update() に向いているのは、毎フレーム確認したい処理です。
たとえば、次のような処理です。
キーボード入力の確認
マウス入力の確認
タッチ入力の確認
タイマー処理
キャラクターの通常移動
UIの表示更新
毎フレーム状態を確認する処理
特に、キー入力の判定は Update() に書くことが多いです。
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("スペースキーが押されました");
}
}Input.GetKeyDown() は、キーが押された瞬間を調べる処理です。
このような入力判定は、基本的に Update() に書くのがわかりやすいです。
Updateで移動するサンプル
たとえば、右方向にキャラクターを動かす場合は、次のように書けます。
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
[SerializeField] float speed = 3f;
void Update()
{
transform.position += Vector3.right * speed * Time.deltaTime;
}
}ここで Time.deltaTime をかけているのがポイントです。
Update() は、パソコンやスマホの性能によって呼び出される回数が変わります。
高性能な環境ではたくさん呼ばれ、重い環境では呼ばれる回数が少なくなります。
そのため、移動処理にそのまま
transform.position += Vector3.right * speed;のように書いてしまうと、環境によって移動速度が変わってしまいます。
そこで Time.deltaTime を使って、1秒あたりの移動量として計算します。
transform.position += Vector3.right * speed * Time.deltaTime;このように書くことで、フレームレートが違っても、なるべく同じ速度で動かせるようになります。
Time.deltaTime に関しては、こちらの記事で詳しく説明しています。

FixedUpdateとは?
FixedUpdate() は、主に物理演算に関係する処理を書くためのイベント関数です。
void FixedUpdate()
{
}Update() が「画面の更新タイミング」に合わせて呼ばれるのに対して、FixedUpdate() は「物理演算のタイミング」に合わせて呼び出されます。
Unityでは、初期設定では FixedUpdate() は基本的に0.02秒に1回呼び出されます。
つまり、1秒間に約50回です。
0.02秒に1回
↓
1秒間に約50回ただし、これは「必ず画面1フレームごとに1回呼ばれる」という意味ではありません。
ゲームが重くなった場合、1フレームの間に FixedUpdate() が複数回呼ばれることもあります。
逆に、フレームレートが高い場合は、あるフレームでは FixedUpdate() が呼ばれないこともあります。
FixedUpdateに向いている処理
FixedUpdate() に向いているのは、Rigidbodyを使った物理処理です。
たとえば、次のような処理です。
Rigidbodyを使った移動
Rigidbody2Dを使った移動
AddForceを使ったジャンプ
物理演算に関係する処理
衝突や重力の影響を受ける動き
たとえば、Rigidbodyに力を加えてジャンプさせる場合は、次のように書けます。
using UnityEngine;
public class PlayerJump : MonoBehaviour
{
Rigidbody rb;
[SerializeField] float jumpPower = 5f;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
if (Input.GetKey(KeyCode.Space))
{
rb.AddForce(Vector3.up * jumpPower);
}
}
}ただし、このコードは説明用です。
実際には、Input.GetKeyDown() のような「押した瞬間」の入力判定は Update() で取得し、その結果を FixedUpdate() で物理処理に使う、という形の方が安全です。
入力はUpdate、物理処理はFixedUpdate
初心者がつまずきやすいのが、
「入力も物理処理も全部FixedUpdateに書いてしまう」
というパターンです。
たとえば、次のようなコードです。
void FixedUpdate()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Jump();
}
}一見よさそうに見えますが、FixedUpdate() は毎フレーム必ず呼ばれるわけではありません。
そのため、キーを押した瞬間を取り逃がす可能性があります。
そこで、入力は Update() で受け取り、物理処理は FixedUpdate() で行うようにします。
using UnityEngine;
public class PlayerJump : MonoBehaviour
{
Rigidbody rb;
[SerializeField] float jumpPower = 5f;
bool jumpRequest;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
jumpRequest = true;
}
}
void FixedUpdate()
{
if (jumpRequest)
{
rb.AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
jumpRequest = false;
}
}
}このようにすると、
Updateで入力を受け取る
FixedUpdateでRigidbodyに力を加える
という役割分担ができます。
Unityでは、この考え方がとても大切です。
FixedUpdateの間隔を変更する方法
FixedUpdate() は、初期設定では0.02秒に1回呼ばれます。
この間隔は、Unityの設定から変更できます。
変更する場所は次の通りです。
1秒間に呼ばれる回数を変更したい場合は、上部メニューの Edit ⇒ Project Settings を立ち上げて、Time の Fixed Timestanp を変更します。

Fixed Timestep の値が、FixedUpdate() の基本的な呼び出し間隔です。
初期値は、
0.02になっています。
これは0.02秒に1回、つまり1秒間に約50回という意味です。
Fixed Timestepを短くする
たとえば、Fixed Timestep を
0.01にすると、0.01秒に1回になります。
つまり、1秒間に約100回です。
物理演算の更新回数が増えるため、動きや判定が細かくなる場合があります。
ただし、その分だけ処理の回数が増えるため、ゲームが重くなる可能性があります。
0.02秒 → 約50回/秒
0.01秒 → 約100回/秒物理処理を多く使っているゲームで不用意に値を小さくすると、負荷が増えるので注意が必要です。
Fixed Timestepを長くする
逆に、Fixed Timestep を
0.033333のようにすると、約0.033秒に1回になります。
これは1秒間に約30回です。
物理演算の回数が減るため、処理は軽くなる場合があります。
ただし、物理演算の更新間隔が長くなるため、動きが少しカクついたり、判定が粗く感じられたりすることがあります。
0.02秒 → 約50回/秒
0.033333秒 → 約30回/秒スマホ向けゲームなどで処理を軽くしたい場合には調整することもありますが、初心者のうちは基本の 0.02 のままで問題ありません。
スクリプトからFixedUpdateの間隔を変更する方法
Fixed Timestep は、スクリプトから変更することもできます。
Time.fixedDeltaTime = 0.02f;たとえば、ゲーム開始時に設定するなら次のように書けます。
using UnityEngine;
public class FixedTimeSetting : MonoBehaviour
{
void Start()
{
Time.fixedDeltaTime = 0.02f;
}
}ただし、実際の開発では、途中で頻繁に Time.fixedDeltaTime を変更することはあまり多くありません。
基本的には、Project SettingsのTimeから設定しておく方がわかりやすいです。
また、Time.timeScale を使ってゲーム全体の時間を遅くしたり止めたりしている場合は、fixedDeltaTime の扱いにも注意が必要です。
初心者向けには、
「FixedUpdateの間隔はProject SettingsのTimeから変更できる」
と覚えておけば十分です。
LateUpdateとは?
LateUpdate() は、Update() の後に呼び出されるイベント関数です。
void LateUpdate()
{
}Update() と同じく、基本的に1フレームに1回呼び出されます。
名前の通り、「遅れて実行されるUpdate」と考えるとわかりやすいです。
LateUpdateはいつ使う?
LateUpdate() は、普段はあまり使わないかもしれません。
実際、簡単なゲームであれば Update() だけで済むことも多いです。
ただし、次のような場面では LateUpdate() を使うと便利です。
カメラ追従
キャラクターの移動後に位置を補正したい
Updateで変わった値をもとに最後に処理したい
複数の処理が終わったあとに向きを調整したい
UIやエフェクトをキャラクターの位置に合わせたい
特に代表的なのが、カメラ追従です。
LateUpdateの代表例:カメラ追従
キャラクターを追いかけるカメラを作る場合を考えてみます。
キャラクターの移動処理を Update() で行っている場合、カメラの追従も Update() に書くと、処理の順番によって少しズレたり、ガタついて見えたりすることがあります。
そこで、キャラクターの移動が終わったあとにカメラを動かすために、LateUpdate() を使います。
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
[SerializeField] Transform target;
[SerializeField] Vector3 offset = new Vector3(0, 2, -10);
void LateUpdate()
{
transform.position = target.position + offset;
}
}このようにすると、
キャラクターが動く
↓
その後でカメラが追いかけるという順番になります。
カメラ追従は、LateUpdate() の使いどころとしてとてもわかりやすい例です。
LateUpdateの便利な事例:向きの補正
もうひとつの例として、キャラクターの向きを最後に補正する処理があります。
たとえば、キャラクターが敵の方向を向く処理を考えます。
移動処理や攻撃処理など、いろいろな処理でキャラクターの向きが変わる場合、最後に向きを整えたいことがあります。
そのような場合、LateUpdate() に補正処理を書くと、Update() の処理が終わった後に最終調整できます。
using UnityEngine;
public class LookAtTarget : MonoBehaviour
{
[SerializeField] Transform target;
void LateUpdate()
{
if (target == null)
{
return;
}
transform.LookAt(target);
}
}このようにすると、毎フレームの最後にターゲットの方向を向くようになります。
3Dゲームでカメラやキャラクターの向きを調整したいときに便利です。
LateUpdateの便利な事例:頭上UIを追従させる
敵キャラクターの頭上にHPバーを表示するような場合にも、LateUpdate() は便利です。
キャラクターの移動が終わったあとに、UIの位置を更新したいからです。
using UnityEngine;
public class HpBarFollow : MonoBehaviour
{
[SerializeField] Transform target;
[SerializeField] Vector3 offset = new Vector3(0, 2f, 0);
void LateUpdate()
{
transform.position = target.position + offset;
}
}このような処理を LateUpdate() に書くと、キャラクターの位置が更新された後にHPバーの位置を合わせることができます。
呼び出される順番のイメージ
ざっくりとしたイメージでは、次のような順番になります。
FixedUpdate
↓
Update
↓
LateUpdateただし、注意点があります。
Update() と LateUpdate() は、基本的に1フレームに1回呼ばれます。
一方で、FixedUpdate() は物理演算のタイミングで呼ばれるため、1フレームに必ず1回とは限りません。
フレームレートが低いと、1フレームの間に複数回呼ばれることがあります。
フレームレートが高いと、あるフレームでは呼ばれないこともあります。
そのため、正確には
FixedUpdateは必要に応じて呼ばれる
Updateは毎フレーム呼ばれる
LateUpdateはUpdateの後に呼ばれると考えるとよいです。
どこに何を書く?早見表

よくある間違い
何でもUpdateに書く
初心者のうちは、とりあえず全部 Update() に書いてしまいがちです。
もちろん、簡単な処理であればそれでも動きます。
ただし、Rigidbodyを使った物理処理まで Update() に書いてしまうと、動きが不安定になることがあります。
物理演算に関係する処理は、基本的に FixedUpdate() を使うと考えておきましょう。
入力をFixedUpdateで取る
FixedUpdate() は物理処理に向いていますが、入力判定にはあまり向いていません。
特に、
Input.GetKeyDown(KeyCode.Space)のような「押した瞬間」を調べる処理は、Update() に書く方が安全です。
FixedUpdate() は毎フレーム必ず呼ばれるわけではないため、入力の瞬間を取り逃がす可能性があります。
おすすめは、
Updateで入力を受け取る
↓
FixedUpdateで物理処理を行うという分け方です。
カメラ追従をUpdateに書いてガタつく
カメラ追従を Update() に書いても動くことはあります。
しかし、キャラクターの移動処理との順番によっては、わずかにガタついて見えることがあります。
そのようなときは、カメラ追従を LateUpdate() に移してみると改善する場合があります。
void LateUpdate()
{
transform.position = target.position + offset;
}LateUpdate() は Update() の後に呼ばれるので、キャラクターが移動した後にカメラが追いかける形にできます。
まとめ
今回は、Unityの
Update
FixedUpdate
LateUpdate
について解説しました。
それぞれの役割を簡単にまとめると、次のようになります。
イベント関数役割Update毎フレームの処理FixedUpdate物理演算の処理LateUpdateUpdate後の処理
もう少し具体的にいうと、
入力はUpdate
物理処理はFixedUpdate
カメラ追従や最終調整はLateUpdateと考えるとわかりやすいです。
特に初心者のうちは、すべてを完璧に使い分ける必要はありません。
まずは、
キー入力はUpdate
RigidbodyはFixedUpdate
カメラ追従はLateUpdate
この3つを覚えておくだけでも、かなり整理しやすくなります。
Unityでは、処理を書く場所によって動きの安定感が変わることがあります。
「どの処理を、どのタイミングで実行したいのか」
を意識できるようになると、スクリプトの理解が一段深まります。
Unity初心者向けの記事をテーマ別にまとめています。
▼ Unity初心者向け記事まとめはこちら
こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。

ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。
いいなと思ったら応援しよう!
よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!