Unity

【Unityゲーム開発テンプレ】制限時間(カウントダウン)&タイムアタック(カウントアップ)の実装方法

本記事内には、アフィリエイトリンクを含む場合があります

アクションゲームやレースゲームなどでは
”時間”という概念を設けることによって、
難易度を調整したり、
一度クリアしたステージでも、もっと早くクリアを促す
といったように飽きさせない工夫を施すことができます。

大規模なストーリーゲームより、カジュアルゲームで実装することが多いといった感じ。

本記事では、この頻出の時間機能の実装方法を解説します。

1.UIの設計

1-1.時間を示すText

CanvasからTextを作成します。

本記事では、カウントダウンとカウントアップを解説するので、
それらの時間を示すように2つ配置します。

Inspectorは図参照

1-2.時間を示すTextMeshPro

せっかくなので、TextMeshProを使ったバージョンも作ります。
(不要な人はスキップください^^;)

TextMeshProは、デザイン性のあるTextを扱う際に有用です。
(Asset Storeで得られるフォントはTextMeshProが多い)

使用するには、UIからTextMeshProを選びます。
ない場合は、WindowタブのPackage ManagerよりTextMashProをInstallして使います。

配置の仕方は、Textと何ら変わりません。
後で説明する、スクリプトで扱う際に、少し変わるくらいです。

1-3.Groupで整理

カウントダウン用とカウントアップ用のTextが入り乱れるので、
整理のためにCreate Emptyから作ります。
(別に作らなくてもいいですけどね^^;)

CdGroupとCuGroupと名付けて格納し、Y座標を調整して、ずらします。

1-4.さらにTextとButton

Textをもう1つ画面中央上に配置します。
これはゲームの開始・終了を示すものです。

そして、時間を止めるためのButtonも作成します。

カウントダウンは時間切れで終了しますが、
カウントアップはクリア条件を設けないと終わりません。

カウントアップを実装するのは、
大抵クリアタイムを意識したゲームだと思うので、
このButtonは、
ゴールに辿り着いたり、ミッションクリアに対応する処理だと見なしてくださいw

2.時間経過(カウントダウン&カウントアップ)のスクリプト

UIの準備が整ったら、スクリプトで動かすだけです。

GameManager.csというスクリプトを作って、ゲーム内にGameManagerという空のゲームオブジェクトを作り、アタッチします。

スクリプトの内容は次の通り↓

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

public class GameManager : MonoBehaviour
{
    [SerializeField] float playTime1;
    float playTime2;
    [SerializeField] Text timeCdText;
    [SerializeField] Text timeCuText;
    [SerializeField] TextMeshProUGUI timeCdTMP;
    [SerializeField] TextMeshProUGUI timeCuTMP;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        playTime1 -= Time.deltaTime; //時間経過で減算
        timeCdText.text = playTime1.ToString("F1"); //四捨五入して小数1桁まで表示
        timeCdTMP.text = playTime1.ToString("F1");

        playTime2 += Time.deltaTime; //時間経過で加算
        timeCuText.text = playTime2.ToString("F1");
        timeCuTMP.text = playTime2.ToString("F1");
    }
}

 

それでは、Inspectorよりスクリプトの項目にTextオブジェクトを紐づけます。
playTime1は制限時間を設定できるようになっています。
ゲーム時間10秒なら、10と入力します。

 

ゲームを実行すると、
CdTextは時間が減り、CuTextは時間が増えていくのがみられます。

3.スタートコールとゴールの設計

ゲームのスタート、時間切れ、ゴールといったリアクションがないと
ゲームの時間実装とはいきませんね^^

ここで、まだ使っていないCallTextとClearButtonの出番です。

次のようにコードを少し追記します↓

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

public class GameManager : MonoBehaviour
{
    [SerializeField] float playTime1;
    float playTime2;
    [SerializeField] Text timeCdText;
    [SerializeField] Text timeCuText;
    [SerializeField] TextMeshProUGUI timeCdTMP;
    [SerializeField] TextMeshProUGUI timeCuTMP;

    [SerializeField] Text callText; // 追記
    bool ready =true; // 追記

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(StartCall()); // 追記
    }

    IEnumerator StartCall() // コルーチンの追記
    {
        callText.text = "よーい";
        yield return new WaitForSeconds(2f);
        callText.text = "スタート!";
        ready = false;
        yield return new WaitForSeconds(1f);
        callText.text = "";
    }

    // Update is called once per frame
    void Update()
    {
        if(ready) // 追記
        {
            return;
        }

        if(playTime1 <= 0) // 時間切れ処理の追記
        {
            ready = true;
            callText.text = "時間切れ~!";
        }

        playTime1 -= Time.deltaTime;
        timeCdText.text = playTime1.ToString("F1");
        timeCdTMP.text = playTime1.ToString("F1");

        playTime2 += Time.deltaTime;
        timeCuText.text = playTime2.ToString("F1");
        timeCuTMP.text = playTime2.ToString("F1");
    }

    public void OnClickClearBtn() // ボタンで呼ぶ関数の追記
    {
        ready = true;
        callText.text = "クリア!";
    }
}

 

readyというboolをUpdate関数のはじめに設ければ、
簡単に時間の停止を制御することができます。
(returnで以下のコードは読まれないため)

スタートがコールされるまでは、ready = true

ゲーム中は、ready = false

・時間切れ(playTime1が0以下)になったら、ready = true
・Goal Buttonが押されたら、ready = true

CallTextの紐付け、
Clear ButtonのOnClickにも関数を紐づけます。

これで実行してみると、
スタートコールや時間切れ、クリアとともに時間の停止が実装されたことがわかります。

このような時間制御は頻出なので
今回のスクリプトはテンプレとして使っちゃってください^^

ABOUT ME
いなも@システマライフハッカー
”仙豆”を開発することを夢見て、健康食品会社で働いていたものの、2016年に出会ったロシアの武術”システマ”こそ、その糸口があると感銘し、勝手にシステマ普及活動を始める。 一方で、クリエイティブなモノ作りが好きで、DX社会で楽しみを見出せる"Unity”を活かして、”スマートかつ快適な暮らし”のヒントを発信している。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA