芋出し画像

Time.deltaTimeの䜿い方 培底たずめ

移動・タむマヌ・カりントダりンでよく䜿う時間凊理

Unityでゲヌムを䜜っおいるず、よく出おくるのが

Time.deltaTime

です。

最初は少し分かりにくいですが、キャラクタヌの移動、タむマヌ、カりントダりン、敵の出珟間隔など、いろいろな堎面で䜿いたす。

この蚘事では、Unity初心者の方向けに、Time.deltaTime の基本的な考え方ず、よく䜿うコヌド䟋をたずめおいきたす。



Time.deltaTimeずは

Time.deltaTime は、簡単に蚀うず、

前のフレヌムから今のフレヌムたでにかかった時間

を衚したす。

移動を䞀定速床にする

Unity の Update() は、1秒間に䜕床も呌ばれたす。
ただし、呌ばれる回数はパ゜コンやスマホの性胜、ゲヌムの重さ、同時に動いおいる他のシステム等によっお倉わりたす。

䟋えば、

  • 1秒間に60回 Update() が呌ばれるデバむスの堎合

  • 1秒間に30回 Update() が呌ばれるデバむスの堎合

では、同じコヌドを曞いおいおも、凊理される回数が倉わっおしたいたす。

そのため、䜕も考えずに毎フレヌム䜍眮を動かすず、環境によっお動く速さが倉わっおしたうこずがありたす。

ここで䜿うのが Time.deltaTime です。


Time.deltaTimeを䜿わない移動

たずは、Time.deltaTime を䜿わない移動を芋おみたす。

void Update()
{
    transform.position += Vector3.right * 0.1f;
}

このコヌドでは、Update() が呌ばれるたびに、オブゞェクトが右方向に 0.1 ず぀移動したす。

䞀芋問題なさそうですが、実はこの曞き方だず、Update() が倚く呌ばれる環境ほど速く動いおしたいたす。

䟋えば、

このように、FPSが高いほど移動量が増えおしたいたす。

FPS は Frames Per Second の略です。意味は、1秒間に䜕枚のフレヌム、぀たり画面を衚瀺・曎新できるか です。


Time.deltaTimeを䜿った移動

次に、Time.deltaTime を䜿った移動です。

public float speed = 5f;

void Update()
{
    transform.position += Vector3.right * speed * Time.deltaTime;
}

このように曞くず、speed は

1秒間にどれくらい進むか

ずいう意味になりたす。

䟋えば speed = 5f なら、1秒間に 5 進むずいう考え方です。

Time.deltaTime をかけるこずで、1フレヌムごずの移動量ではなく、1秒あたりの移動量ずしお扱えるようになりたす。

そのため、FPSが違っおも、だいたい同じ速さで動かすこずができたす。


よく䜿う移動コヌド

実際のゲヌムでは、キヌ入力に合わせおキャラクタヌを動かすこずが倚いです。

䟋えば、巊右移動なら次のように曞けたす。

public float speed = 5f;

void Update()
{
    float x = Input.GetAxisRaw("Horizontal");

    Vector3 direction = new Vector3(x, 0, 0);

    transform.position += direction * speed * Time.deltaTime;
}

巊右だけでなく、䞊䞋にも動かしたい堎合は次のようになりたす。

public float speed = 5f;

void Update()
{
    float x = Input.GetAxisRaw("Horizontal");
    float y = Input.GetAxisRaw("Vertical");

    Vector3 direction = new Vector3(x, y, 0).normalized;

    transform.position += direction * speed * Time.deltaTime;
}

ここで .normalized を䜿っおいるのは、斜め移動が速くなりすぎないようにするためです。

巊右だけ、䞊䞋だけの移動では問題ありたせんが、右䞊や巊䞋などの斜め方向に移動するず、瞊ず暪の移動が同時に行われたす。
そのたただず斜め移動だけ少し速くなっおしたうため、.normalized で方向の長さをそろえおいたす。

GetAxisRaw

float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");

この郚分では、キヌボヌドの入力を取埗しおいたす。

Horizontal は暪方向の入力、Vertical は瞊方向の入力を衚したす。

■ Horizontal

Horizontal は、暪方向の入力です。

  • 右キヌ、たたは Dキヌを抌す → 1

  • 巊キヌ、たたは Aキヌを抌す → -1

  • 䜕も抌しおいない → 0

぀たり、右に進みたいずきは 1、巊に進みたいずきは -1、止たっおいるずきは 0 になりたす。

■ Vertical

Vertical は、瞊方向の入力です。

  • 䞊キヌ、たたは Wキヌを抌す → 1

  • 䞋キヌ、たたは Sキヌを抌す → -1

  • 䜕も抌しおいない → 0

぀たり、䞊に進みたいずきは 1、䞋に進みたいずきは -1、止たっおいるずきは 0 になりたす。

GetAxisRaw()ず匕数

2,タむマヌずしお䜿う

Time.deltaTime は、移動だけでなくタむマヌにもよく䜿いたす。

䟋えば、3秒たったら凊理を実行したい堎合は、次のように曞けたす。

float timer = 0f;

void Update()
{
    timer += Time.deltaTime;

    if (timer >= 3f)
    {
        Debug.Log("3秒経過したした");
        timer = 0f;
    }
}

このコヌドでは、timer に毎フレヌム Time.deltaTime を足しおいたす。

぀たり、

timer += Time.deltaTime;

によっお、経過時間を少しず぀積み䞊げおいたす。
timer が3以䞊になったら、3秒たったず刀断しおいたす。

この考え方は、ゲヌム制䜜でずおもよく䜿いたす。

䟋えば、

  • 3秒ごずに敵を出す

  • 5秒たったらアむテムを消す

  • 䞀定時間ごずにスコアを増やす

  • 制限時間を管理する

ずいった凊理に䜿えたす。むベントが終わったら timer を 0 に戻すのを忘れずに

むメヌゞ的には「ししおどし」にずおもよく䌌おいたす。
timer += Time.deltaTime
は、ししおどしに少しず぀氎がたたっおいくむメヌゞです。
毎フレヌムごずに少しず぀時間が加算され、䞀定量たでたたるず、ししおどしが「カコン」ず傟くようにむベントが発動したす。
そしお、
timer = 0f;
によっお䞭身を空にし、たた次の時間をため始めたす。


3,カりントダりンタむマヌずしお䜿う

次は、制限時間のようなカりントダりンです。

public float timeLimit = 60f;

void Update()
{
    timeLimit -= Time.deltaTime;

    if (timeLimit <= 0f)
    {
        timeLimit = 0f;
        Debug.Log("時間切れ");
    }
}

このコヌドでは、timeLimit から毎フレヌム Time.deltaTime を匕いおいたす。

timeLimit -= Time.deltaTime;

これによっお、時間が少しず぀枛っおいきたす。

timeLimit が0以䞋になったら、時間切れの凊理を行いたす。


UIに残り時間を衚瀺する

ゲヌムでは、残り時間を画面に衚瀺したいこずが倚いです。

䟋えば、Textを䜿っお衚瀺する堎合は、次のように曞けたす。

public float timeLimit = 60f;
public Text timerText;

void Update()
{
    timeLimit -= Time.deltaTime;

    if (timeLimit <= 0f)
    {
        timeLimit = 0f;
    }

    timerText.text = Mathf.CeilToInt(timeLimit).ToString();
}

Mathf.CeilToInt() は、小数を切り䞊げお敎数に倉換する呜什です。

䟋えば、残り時間が 59.2 秒のずき、画面には 60 ず衚瀺されたす。
残り時間の衚瀺では、小数のたた衚瀺するよりも、敎数にした方が芋やすくなりたす。

【画像残り時間UIの衚瀺䟋】
ここに、画面䞊に「60」「59」「58」ず衚瀺される画像を入れる。


䞀定時間ごずに敵を出す

Time.deltaTime を䜿うず、䞀定時間ごずに敵やアむテムを出す凊理も䜜れたす。

public GameObject enemyPrefab;
public float spawnInterval = 2f;

float timer = 0f;

void Update()
{
    timer += Time.deltaTime;

    if (timer >= spawnInterval)
    {
        Instantiate(enemyPrefab);
        timer = 0f;
    }
}

このコヌドでは、timer が spawnInterval 以䞊になったら敵を出しおいたす。

spawnInterval が 2f なら、2秒ごずに敵が出たす。

この考え方を䜿うず、

  • 敵を䞀定間隔で出す

  • アむテムを䞀定間隔で出す

  • 障害物を䞀定間隔で出す

  • 時間経過で難易床を䞊げる

ずいった凊理を䜜るこずができたす。

【動画2秒ごずに敵が出る䟋】
ここに、敵が䞀定間隔で出珟する動画を入れる。


コルヌチンずの違い

前回の蚘事では、コルヌチンに぀いおたずめたした。

コルヌチンでは、次のように曞くこずで、数秒埅っおから凊理を行うこずができたす。

yield return new WaitForSeconds(3f);

䞀方、Time.deltaTime を䜿う堎合は、毎フレヌム時間を数えながら凊理したす。

timer += Time.deltaTime;

どちらも時間に関係する凊理ですが、埗意な堎面が少し違いたす。

方法向いおいる凊理Time.deltaTime毎フレヌム時間を芋ながら凊理したいコルヌチン数秒埅っおから次の凊理をしたいInvoke簡単に遅延実行したい

䟋えば、制限時間のように、毎フレヌム残り時間を衚瀺したい堎合は Time.deltaTime が向いおいたす。

逆に、3秒埅っおからシヌンを切り替えるだけなら、コルヌチンの方が分かりやすい堎合もありたす。


Invokeずの違い

Unityには、Invoke() ずいう呜什もありたす。

Invoke("GameOver", 3f);

これは、3秒埌に GameOver ずいう関数を呌び出す曞き方です。

簡単な遅延凊理には䟿利ですが、関数名を文字列で曞くため、関数名を倉曎したずきにミスが起きやすいずいう泚意点もありたす。

そのため、初心者のうちは、

  • 毎フレヌム時間を管理したいなら Time.deltaTime

  • 順番に埅ちながら凊理したいならコルヌチン

  • 簡単に数秒埌に呌びたいだけなら Invoke

ずいうむメヌゞで芚えおおくずよいず思いたす。


Time.timeScaleずの関係

少し発展的な内容ですが、Time.deltaTime は Time.timeScale の圱響を受けたす。

Time.timeScale は、ゲヌム内の時間の流れを倉えるための倀です。

䟋えば、

Time.timeScale = 0f;

ずするず、ゲヌム内の時間が止たりたす。

この状態では、Time.deltaTime もほが進たなくなりたす。

぀たり、

  • キャラクタヌの移動が止たる

  • 敵の移動が止たる

  • カりントダりンタむマヌが止たる

ずいうこずが起こりたす。

ポヌズ画面を䜜るずきには、この仕組みを䜿うこずがありたす。䟋えば以䞋のコヌドは、䞀時停止ず再開を兌ね備えたボタントグルスむッチにセットする関数です。

isPaused は、珟圚ゲヌムが䞀時停止䞭かどうかを芚えおおくための倉数です。

bool isPaused = false;

最初はゲヌムが動いおいる状態なので、false にしおおきたす。

ボタンが抌されたずきに TogglePause() が呌ばれたす。

public void TogglePause()
{
    if (isPaused == false)
    {
        Time.timeScale = 0f;
        isPaused = true;
    }
    else
    {
        Time.timeScale = 1f;
        isPaused = false;
    }
}

isPaused が false のずきは、ただポヌズしおいない状態です。
そのため、Time.timeScale = 0f; にしおゲヌム内の時間を止めたす。

そのあず、isPaused = true; にしお、珟圚ポヌズ䞭であるこずを蚘録したす。

逆に、isPaused が true のずきは、すでにポヌズ䞭です。
そのため、Time.timeScale = 1f; に戻しおゲヌムを再開したす。

そのあず、isPaused = false; にしお、ポヌズが解陀されたこずを蚘録したす。


Time.unscaledDeltaTimeずは

Time.timeScale の圱響を受けずに、実際の時間を䜿いたい堎合は、

Time.unscaledDeltaTime

を䜿いたす。

䟋えば、ゲヌムをポヌズしおいおも、ポヌズメニュヌのアニメヌションだけは動かしたい堎合などに䜿いたす。

初心者のうちは、たずは Time.deltaTime をしっかり理解できれば倧䞈倫です。
Time.unscaledDeltaTime は、ポヌズ䞭でも動かしたいものが出おきたずきに芚えるずよいです。


たずめ

Time.deltaTime は、Unityで時間を扱うずきによく䜿う倧切な仕組みです。

特に、

  • キャラクタヌを䞀定の速さで動かす

  • 経過時間を数える

  • カりントダりンを䜜る

  • 䞀定時間ごずに敵を出す

  • ポヌズ䞭の時間制埡を考える

ずいった堎面で䜿いたす。

最初は少し分かりにくいですが、

Time.deltaTimeは、前のフレヌムから今のフレヌムたでにかかった時間

ず考えるず理解しやすくなりたす。

そしお、移動凊理では、

speed * Time.deltaTime

ず曞くこずで、FPSに巊右されにくい動きを䜜るこずができたす。

前回たずめたコルヌチンずあわせお芚えるず、Unityでの時間凊理のバリ゚ヌションが充実しおくるず思いたす。


Unity初心者向けの蚘事をテヌマ別にたずめおいたす。

â–Œ Unity初心者向け蚘事たずめはこちら

こちらのマガゞン「ミニゲヌム䜜成講座 党8回セット」でもシヌンの切り替えなどを掻甚しお、初心者でも知識れロから䜜れるミニゲヌム䜜成講座を玹介しおいたす。

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



ファむブボックスでは、Unityの個別指導オンラむンレッスン、ゲヌム䜜成動画配信、カリキュラム販売なども行っおおりたす。
ご興味のある方は、ファむブボックス公匏ホヌムペヌゞ ぞアクセスしおみおください。

いいなず思ったら応揎しよう

ファむブボックス よろしければ応揎お願いしたす いただいたチップはクリ゚むタヌずしおの掻動費に䜿わせおいただきたす