ゲーム化!tomo_manaのブログ

ゲーム化!tomo-manaのブログ

Unityでゲームを作る方法について紹介しています

Unity バックグラウンド中はUpdate()が呼ばれない!? (Unity 2020.3.26f1)

f:id:tomo_mana:20220330165430p:plain

バックグラウンド中は Update() が呼ばれません。


もしかすると、Androidアプリを作っているUnityクリエイターさんの間では常識すぎて誰も書いていないということなのかもしれませんが、私は一瞬困惑したので、記事としてまとめておきます。

バックグラウンド移行と復帰

バックグラウンドへの移行と復帰は、以下のサイトにあるコードで確認ができます(非常に汎用性が高いコードです)。
kan-kikuchi.hatenablog.com

時間経過

アプリがフォアグラウンドの間にある時間だけ見る場合は Time.timeTime.deltaTime を使うことができます。バックグラウンド中の経過時間を考慮する場合は、System.DateTime を使って計算します。


DateTimeを使った計算例(ゲーム開始からの時間)

TimeUtil .cs

using System;

public static class TimeUtil 
{
    private static DateTime StartTime = DateTime.Now;

    // ゲーム開始からの時間を取得する
    public static long GetElapsedTime(DateTime dateTime)
    {
        return (long)(dateTime - StartTime).TotalSeconds;
    }
}


絶対時間の計算方法は、こちらを参考にしました(こちらはUNIX時間の計算方法です)。
smartgames.hatenablog.com


先ほどのコードを利用して、簡単なコンポーネントを一つ作ってみます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using TMPro;

public class TimerTest : MonoBehaviour
{
    [SerializeField]
    TextMeshProUGUI text;
    
    // Start is called before the first frame update
    void Start()
    {
        // 早すぎるとDeltaTimeが目視できないのでFPS落とす
        Application.targetFrameRate = 30;
    }
    private float time, delta, max = 0, abstime;
    
    // Update is called once per frame
    void Update()
    {
        delta = Time.deltaTime;
        if( max < delta ){
            max = delta;
        }
        time = Time.time;
        abstime = TimeUtil.GetElapsedTime(DateTime.Now);
        text.text = "elapsedTime: " + abstime + 
                    "\nTime.time: " + Math.Round(time, 0, MidpointRounding.AwayFromZero) + 
                    "\nTime.DeltaTime Max = " + Math.Round(max, 2, MidpointRounding.AwayFromZero) + 
                    "\nTime.DeltaTime = " + Math.Round(delta, 2, MidpointRounding.AwayFromZero);
    }
}

画面にText(上記の場合はTextMeshProUGUIを使用しています)を張り、上記のコンポーネントにアタッチして実行すると、いくつかの経過時間を表示してくれます。

f:id:tomo_mana:20220325094258g:plain
経過時間

バックグラウンドに落として戻ってくると、Time.time はフォアグラウンドにいる間だけ動作しており、Time.deltaTime はフォアグラウンドに居た時間内での差分を計算していました。また、DateTimeを使った場合は、バックグラウンドに移行している時間を含んだ開始からの時間を計算できていました。


Unityエディタ上でも確認できますが、実機で一度確認してみるのがおススメです。

バックグラウンドに移行する操作

バックグラウンド移行・復帰する操作として、Android では以下のようなものがありました。

・タスク一覧表示(■ボタン)
・ホーム(●ボタン)
・スリープ(端末を操作しないで放置→自然にスリープ)
・強制スリープ(電源ボタン短押し)
・省電力モード(電池残量減)
・(アプリからスリープを強制解除した場合、画面タップなどで)キーガード表示 ※前述のバックグラウンド・フォアグラウンド移行の回数が一致しない。


(以上)