はこねのはこ

はこねさんの備忘録

Time.timeScale = 0であっても時間に関する処理がしたい時にTime.unscaledDeltaTimeを使用した話

はじめに

ポーズ機能を実装しようとしました。
ポーズからゲームを再開しようとした時、いきなり始まるのではなく、 プログレスバーのような円ゲージを用意して開始のタイミングを取りやすいようにしたのですが、 ポーズ中はTime.deltaTimeを使用した円ゲージの処理も止まってしまいました。

ゲーム時間の停止は

Time.timeScale = 0;

を使用しています。 Time.deltaTimeは止まってしまう(今思えばあたりまえ)ので、 この状態でも時間制御がしたかったので調べたことをメモ。

解決策

Time.unscaledDeltaTimeを使います。
timeScaleの影響を受けないようです。

できたもの

できました。
ポーズ中はTime.timeScale = 0としていて、
オレンジのアイコンはTime.unscaledDeltaTimeを使用しています。

アイコンイメージの設定

f:id:hakonebox:20190102201013p:plain

コード例

GameManager.cs

   public static void AdjustGameTime(float speed){
        Time.timeScale = speed;
    }

UIController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIController : MonoBehaviour {

    public GameObject PauseUI;
    public GameObject LockUI;
    public Image LockIcon;
    const float openLockTime = 1.0f;//[s]
    bool openlock = false;

    // Use this for initialization
    void Start () {
        PauseUI.SetActive(false);
        LockUI.SetActive(false);
    }
    
    // Update is called once per frame
    void Update () {
        UpdateLockGauge();
    }

    public void OnPauseButtonClick() {
        Debug.Log("PauseButton");
        ClearLockGauge();
        GameManager.AdjustGameTime(0);
        PauseUI.SetActive(true);
    }

    public void OnContinueButtonClick() {
        Debug.Log("ContinueButton");
        PauseUI.SetActive(false);
        SetLockGauge();
    }

    void SetLockGauge(){
        LockUI.SetActive(true);
        LockIcon.fillAmount = 1;
        openlock = true;
    }

    void ClearLockGauge(){
        LockUI.SetActive(false);
        openlock = false;
    }

    void UpdateLockGauge(){
        if(openlock){
            if(LockIcon.fillAmount > 0){
                LockIcon.fillAmount -= 1.0f / openLockTime * Time.unscaledDeltaTime;
            }else{
                openlock = false;
                GameManager.AdjustGameTime(1);
            }
        }
    }
}