Unity & C# 学習教材

Update メソッドと連続実行

Start メソッドがゲーム開始時に1回だけ実行されるのに対し、Update メソッドは毎フレーム繰り返し呼び出され続けます。このページでは Update の仕組みを体験し、オブジェクトをスクリプトで動かす基本を学びます。

学習目標

このページを読み終えると、以下のことができるようになります。

前提知識


1. Update メソッドとは

UpdateStart と並ぶ MonoBehaviour の基本メソッドです。

メソッド 実行タイミング 主な用途
Start ゲーム開始時に 1回 初期配置・初期化
Update 毎フレーム 繰り返し 入力処理・継続的な移動

1秒間に画面が更新される回数をフレームレートと呼びます。60fps(フレーム毎秒)の環境では、Update は1秒間に60回呼び出されます。


2. Debug.Log で連続実行を体験する

まず Debug.Log を使って、Update が繰り返し呼ばれていることを確認します。

1
2
3
4
5
6
7
8
9
using UnityEngine;

public class UpdateSample : MonoBehaviour
{
    private void Update()
    {
        Debug.Log("Update が呼ばれました");
    }
}

実行結果

このスクリプトをゲームオブジェクトにアタッチして実行すると、Console ビューにメッセージが連続して出力され続けます。Start に同じコードを書いた場合は1回だけ出力されることと比べてみましょう。


3. transform.Translate でオブジェクトを動かす

移動処理の基本は、Update で毎フレーム少しずつ座標を更新することです。これを繰り返すことで、オブジェクトは継続的に動いて見えるようになります。

先に、スクリプトから動かすゲームオブジェクトを作成しましょう。メニューバーの GameObject → 3D Object → Cube 項目を選択して立方体を追加してください。

Cube ゲームオブジェクトを追加する

継続的な座標更新は Update メソッドで毎フレーム transform.position を書き換える方法で実装できます。

1
transform.position += new Vector3(0.1f, 0, 0);

同様の意味で、より簡潔に移動を書けるメソッドとして Transform.Translate も用意されています。今回は、これを使ってみましょう。

Transform.Translate — Transform を指定した方向・距離だけ移動します。

書式:Transform.Translate メソッド

1
public void Translate(Vector3 translation);
パラメータ 説明
translation Vector3 移動する方向と距離

まずは X 方向の移動量を直接指定してみます。

1
2
3
4
5
6
7
8
9
using UnityEngine;

public class UpdateSample : MonoBehaviour
{
    private void Update()
    {
        transform.Translate(new Vector3(0.1f, 0, 0));
    }
}

これを実行すると、オブジェクトが右方向に動き続けます。


new Vector3(0.1f, 0, 0) はX方向にだけ移動する指定ですが、毎回この書き方をするのは冗長です。Vector3 にはよく使う方向があらかじめ定数として用意されています。

書式:Vector3 方向定数

1
2
3
4
5
6
Vector3.right    // new Vector3( 1,  0,  0) と同じ(右)
Vector3.left     // new Vector3(-1,  0,  0) と同じ(左)
Vector3.up       // new Vector3( 0,  1,  0) と同じ(上)
Vector3.down     // new Vector3( 0, -1,  0) と同じ(下)
Vector3.forward  // new Vector3( 0,  0,  1) と同じ(奥)
Vector3.back     // new Vector3( 0,  0, -1) と同じ(手前)

これらの定数には「1フレームあたりいくつ動くか」を掛けて使います。Vector3.right * 0.1fnew Vector3(0.1f, 0, 0) と同じ意味になります。

1
2
3
4
5
6
7
8
9
using UnityEngine;

public class UpdateSample : MonoBehaviour
{
    private void Update()
    {
        transform.Translate(Vector3.right * 0.1f);  // new Vector3(0.1f, 0, 0) と同じ
    }
}

4. フレームレート依存の問題

上のコードには問題があります。0.1f1フレームあたりの移動量です。フレームレートが異なると、同じコードでも速度が変わってしまいます。

フレームレート 1秒あたりの Update 呼び出し回数 1秒あたりの移動量
30 fps 30回 3.0
60 fps 60回 6.0
120 fps 120回 12.0

端末の性能や負荷によってフレームレートは変動するため、環境によって速度が変わるという不安定な挙動になります。


5. Time.deltaTime でフレームレートに依存しない移動

この問題を解決するのが Time.deltaTime です。

Time.deltaTime — 前のフレームからの経過時間(秒)を返します。

書式:Time.deltaTime プロパティ

1
public static float deltaTime { get; }

60fps では約 0.0167、30fps では約 0.0333 の値になります。つまりフレームレートが高いほど小さい値です。移動量に Time.deltaTime を掛けることで、フレームレートが変わっても1秒あたりの移動量が一定になります。

1
2
3
4
5
6
7
8
9
10
using UnityEngine;

public class UpdateSample : MonoBehaviour
{
    private void Update()
    {
        // 1秒あたり 3.0 進む(フレームレートによらず一定)
        transform.Translate(Vector3.right * 3.0f * Time.deltaTime);
    }
}

💡 ポイント: Time.deltaTime を掛けた場合のもう一方の数値(ここでは 3.0f)は「1秒あたりの移動量(速度)」を意味します。Time クラスには他にも時間管理に役立つプロパティがあります。詳細は Time クラスと時間制御 で扱います。


まとめ


理解度チェック

以下の問いに答えられるか確認しましょう。

  1. StartUpdate の実行タイミングの違いを説明してください。
  2. transform.Translate(Vector3.up * 2.0f * Time.deltaTime) を実行すると、オブジェクトはどのように動きますか?
  3. Time.deltaTime を掛けないとどのような問題が起きますか?
解答を見る
  1. Start はゲーム開始時に 1回だけUpdate毎フレーム繰り返し 実行される。
  2. 上方向(Y+)に 1秒あたり 2.0 の速度で動き続ける。
  3. フレームレートが高い端末ほど速く動き、低い端末ほど遅く動く。環境によって速度が変わる不安定な動作になる。

次のステップ

Input System で入力操作 では、キーボード入力を受け取ってオブジェクトを操作する方法を学びます。