【Unity】現在の時間を取得できるDateTime.Nowメソッド

DateTime.Nowメソッド Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「Unityで現在の時間を取得したい!」

「特定の時間帯における処理を作りたい!」

というお悩みの方に向けた内容となっています。

Unityで現在の時間を取得する際は、DateTime構造体で定義されているNowというメソッドを使うことで取得できます。

このDateTime.Nowは、その端末における現在の日時を取得できるメソッドで、年・月・日・時・分・秒・ミリ秒に分けて取得することができます。

DateTime.Nowを使うことで、例えば、ゲーム内で現在の時刻を表示させたり、時間に応じた処理を作ることができるようになります。

そこで、このページでは、Unityで現在の時間を取得することができるDateTime.Nowのメソッドについて、どんなメソッドなのか、使い方をまとめていきます。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

Unityで現在の時間を取得する方法

それでは、Unityで現在の時間を取得する方法について紹介していきます。

DateTime.Nowメソッドで端末の時間を取得

Unityで現在の時間を取得する場合、DateTime構造体Nowというメソッドで取得することができます。

そもそもこのDateTime構造体とは、日付と時刻をまとめているデータ型のことで、Unityの機能ではなく、C#で使うことができる構造体になっています。

そして、DateTime構造体で端末上における現在の日時を取得できるメソッドとして、Nowメソッドが定義されています。

Nowメソッドを使う際は、以下のように記述してあげます。

using System;   // C#の機能を使うので記述
using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        Debug.Log(DateTime.Now);    // 現在の時間を取得してコンソールウィンドウに表示
    }
}

まず、1行目でC#の機能を利用するため、「using System;」という記述を行っています。

そして、8行目で「DateTime.Now」と記述することで、現在の日時を取得することができます。

実際にこれでゲームを実行してみると、

上記のように取得できているのが分かります。

DateTime構造体からそれぞれの値を取り出す

DateTime構造体は、その日時データから以下のプロパティを使って、それぞれの値を取り出すことができます。

  • Year:年
  • Month:月
  • Day:日
  • Hour:時
  • Minute:分
  • Second:秒
  • Millisecond:ミリ秒

ここでは、上記のプロパティを使って、ゲーム内に現在の時間をリアルタイムで表示させる処理を作ってみます。

まず、以下のように時刻を表示させるTextMeshProのオブジェクトを配置しておきます。

そして、このオブジェクトに以下のスクリプトをアタッチしておきます。

using System;   // C#の機能を使うので記述
using TMPro;    // TextMeshProを使うので記述
using UnityEngine;

public class Time : MonoBehaviour
{
    TextMeshProUGUI tmp;
    DateTime now;

    void Start()
    {
        tmp = GetComponent<TextMeshProUGUI>();  // TextMeshProコンポーネントを取得
        DisplayTime();
    }

    void Update()
    {
        // 秒数が変更した場合
        if (now.Second != DateTime.Now.Second)
        {
            DisplayTime();
        }
    }

    void DisplayTime()
    {
        now = DateTime.Now;     // 現在の時間を取得
        tmp.text = now.Year + "年" + now.Month + "月" + now.Day + "日" + now.Hour + "時" + now.Minute + "分" + now.Second + "秒";     // 時間を表示する処理
    }
}

12行目でTextMeshProコンポーネントを取得するために、GetComponentメソッドを使っています。

時間を取得して表示させる処理として、25行目でDisplayTimeというメソッドを定義して、その中の27行目でNowメソッドで時間を取得し、28行目でtextの値にDateTime構造体のプロパティを使って、それぞれの値をテキストで表示するようにしています。

そして、このDisplayTimeメソッドをStartUpdateの中でそれぞれ記述して、表示させる処理をおこなっています。

ゲームを実行してみると、

上記のように日時をリアルタイムで表示させることができました。

ちなみに、DateTime構造体は、ToStringメソッドの引数を使って、時間の表記方法を変えて文字列に変換することもできます。

DateTime構造体の値引数の書式指定子
yyyy
MM
dd
時間HH
mm
ss

そのため、先ほどのスクリプトの28行目部分を以下のように変更しても、同じ処理が行われるようになります。

using System;
using TMPro;
using UnityEngine;

public class Time : MonoBehaviour
{
    TextMeshProUGUI tmp;
    DateTime now;

    void Start()
    {
        tmp = GetComponent<TextMeshProUGUI>();
        DisplayTime();
    }

    void Update()
    {

        if (now.Second != DateTime.Now.Second)
        {
            DisplayTime();
        }
    }

    void DisplayTime()
    {
        now = DateTime.Now;
        tmp.text = now.ToString("yyyy年MM月dd日HH時mm分ss秒");    // 文字列に変換して表示
    }
}

朝・昼・夜で表示を変更する処理

ここからは、DateTime.Nowメソッドを実際に使って、朝と昼と夜で表示が変わるような簡単な処理を作ってみます。

まず、以下のように四角いオブジェクトと、時刻を表示させるTextMeshProオブジェクトを配置しておきます。

そして、TextMeshProオブジェクトに、先ほどと同様に時刻を表示させるスクリプトをアタッチしておきます。

using System;
using TMPro;
using UnityEngine;

public class Time : MonoBehaviour
{
    TextMeshProUGUI tmp;
    public DateTime now;    // public修飾子を付けておく

    void Start()
    {
        tmp = GetComponent<TextMeshProUGUI>();
        DisplayTime();
    }

    void Update()
    {

        if (now.Second != DateTime.Now.Second)
        {
            DisplayTime();
        }
    }

    void DisplayTime()
    {
        now = DateTime.Now;
        tmp.text = now.ToString("yyyy/MM/dd\nHH:mm:ss");
    }
}

ここでは、他のクラスからも時刻を取得できるようにしたいので、8行目のDateTime型の変数を宣言する際にpublic修飾子を付けています。

次に、この取得した時間に応じて、四角いオブジェクトの色が変化する処理を作りたいので、以下のスクリプトを四角のオブジェクトにアタッチしていきます。

using UnityEngine;

public class SquareController : MonoBehaviour
{
    [SerializeField] Time time;   // Time型の変数を宣言する
    SpriteRenderer sr;

    // 現在の時間帯を定義
    enum TimeZone
    {
        None,
        Morning,
        Afternoon,
        Night
    }
    TimeZone timeZone;

    void Start()
    {
        sr = GetComponent<SpriteRenderer>();    // SpriteRendererコンポーネントを取得
    }

    void Update()
    {
        // 午前の場合の処理
        if (time.now.Hour >= 6f && time.now.Hour < 12f && timeZone != TimeZone.Morning)
        {
            sr.color = Color.red;       // 赤色に変更
            timeZone = TimeZone.Morning;
        }
        // 午後の場合の処理
        if (time.now.Hour >= 12f && time.now.Hour < 17f && timeZone != TimeZone.Afternoon)
        {
            sr.color = Color.yellow;    // 黄色に変更
            timeZone = TimeZone.Afternoon;
        }
        // 夜の場合の処理
        if ((time.now.Hour >= 17f || time.now.Hour < 6f) && timeZone != TimeZone.Night)
        {
            sr.color = Color.gray;      // 灰色に変更
            timeZone = TimeZone.Night;
        }
    }
}

5行目でTime型の変数を宣言して、SerializeField属性を付けてインスペクターからTextMeshProのオブジェクトを選択しておきます。

今回は、

6時~12時「午前」赤色に変更
12時~17時「午後」黄色に変更
17時~6時「夜」灰色に変更

としたいので、26行目から42行目でHourプロパティを使って、それぞれの条件に応じて分岐処理を作っています。

なお、Updateメソッド内で処理を作っているので、何度も処理が行われないように9行目でenum型を定義して、変数を作り制御しています。

これでゲームを実行してみると、

それぞれの時間に合わせてオブジェクトの色が変更できているのが分かります。

この仕組みを活用することで、夜だけに表示させる敵を作ったり、特定の時間しか入れない領域などを作ることができます。

端末時間なので意図的にいじれてしまう

DateTime.Nowメソッドは、現在時間を簡単に取得することができますが、あくまでも端末(PCやスマホ)での内部の時間を取得しています。

つまり、端末の時間設定を変更すると、その変更した時間を取得してしまうことになるため、意図的にいじることができてしまいます。

例えば、特定の時間帯のみでイベントを行うような場合に、DateTime.Nowメソッドで処理を作ってしまうと、ユーザーが端末の時間を変更するだけで、実際にはイベントが行われていない時間帯なのに、行われてしまうということが発生してしまいます。

そのため、DateTime.Nowメソッドで取得する時間は、あくまでも端末内のローカル時間となるため、注意しておきましょう。

もしオンラインゲームなどで、ゲームをプレイするすべてのユーザーに対して同じ時刻にイベントを発生させるような場合は、特定のサーバーから時間を取得してきて、その時間を使ってゲーム内処理を作ってあげることで、可能になります。

まとめ

このページでは、Unityで現在の時間を取得するDateTime.Nowメソッドについて、どんなメソッドなのか、使い方までをまとめていきましたが、いかがでしたでしょうか?

DateTime.Nowメソッドは、端末内部の日時を取得することで、ゲーム内に表示したり、時間を使った処理を行うことができるメソッドです。

取得した日時はDateTime構造体という型で管理されていて、年・月・日・時・分・秒・ミリ秒のそれぞれの単位毎に値を抜き出すことができます。

また、Nowメソッドはあくまでも端末内部の日時となり、ユーザーが端末の時間を変更することで、取得する時間も変更されてしまうため、注意しておきましょう。

最後までお読みいただきまして、ありがとうございました!

コメント