【Unity】Unityで現実の時間を取得する方法(+現実での経過時間を計算)

現在Unityでクリッカーゲームを作っています。

そこでゲーム終了してから次の起動までの現実での経過時間をつかって何か要素を追加したいと思いいろいろ調べていました。

しかし検索してもいろんな記事を読み漁ることになってなかなかに時間がかかったのでUnityの現実時間系についてまとめようと思います。

 

まずそもそもなのですが、現実時間の取得はUnityの機能では取り出すことができません。(言い回しがあっているかはわかりません)

C#の機能を用いて取得を行います。

要はC#の機能を使うためにスクリプトの最初にusing Systemを宣言する必要があるということです。それだけです。

そして注意点は型(intとかstringとか)がいろいろとごちゃごちゃするので自分が今どの型で取得しているのかは留意して扱う必要があります。

 

では実際に現実時間の取得方法をまとめていきます。

 

①現在の時間の取得

DateTime awakeDateTime = DateTime.Now;

これで現在の日時が

awakeDateTime = (年,月,日,時,分,秒,1/100秒)

の形で取得できます。これはDateTime型で取得でき、調べるとすぐに見つかることではないかなと思います。

 

なのですがおそらくUnityで現実の時間を取得したい人はおそらくその取得した時間を用いていろいろ数字の計算をしたいのではないのではなかろうかということです。

現状であるとDateTime型なのでint型で数字として取得して計算が出来ません。

そこで

int year = awakeDateTime.Year;

とすると現在の西暦がint型で取得が出来ます。

その要領でMonth,Day,Hour,Minute・・・もそれぞれint型で取得ができます。

参考にしたブログがありますので記載します。

r-y-t.com

 

②経過時間の計算

現実の経過時間はTimeSpanを用いると簡単に取得ができます。

これの何がいいかというとDateTime型で取得した2つの日時をそのまま足し引きできる点にあります。

DateTime = awakeDateTime  //今回のアプリ起動時間

DateTime = preDateTime //前回のアプリ起動時間

とすると

TimeSpan span = awakeDateTime - preDateTime

のように打ち込むと差分を求めることが出来ます。ただこれもまたDateTime型なので注意が必要です。

今回も

int year = span.Year;

とするとint型で取得することができます

ただこれにはもう一点重要なことがあります。

たとえば

preDateTimeが

2000年1月1日0時0分0.000秒で

awakeDateTimeが

2000年1月1日1時1分0.000秒だった場合(経過時間は1時間1分

int minutes = span.Minute;は

minutes = 1で出力されます。

経過時間が1時間1分なのに出力は61分ではなく1分となります。

つまりそれぞれのDateTime型の同じ単位の差し引きしかしてくれないということです。

 

これもこれで使える場面はあると思いますが、経過時間を一つの単位(時間・分など)で取得したいですよね。

この解決策もあります。

double totalMimutes = span.TotalMinutes;

これで一発解決です。

tatalMinutes = 61で取得できます。TotalMinutesの部分をTotalHoursにすると時間が取得できます。

ただこのTotal~を使う場合にも型の注意点があります。

少数の出てくる数値になるためdouble型で取得することになるということです。

したがってint型の変数にしたいのであれば型の変換をする必要があります。

 

③時間の保存(PlayerPrefs)

アプリを起動した時間や終了した時間を保存する場合についてまとめます。

保存はPlayerPrefsを多くの人が使っていると思うのですが、PlayerPrefsはString型・int型・float型でしか保存できません。

つまりDateTime型のままだと保存はできないということです。

そのため、DateTime型String型に変換して保存を行います。

PlayerPrefs.SetString("SAVEDATETIME", awakeDateTime.ToBinary().ToString());

これでString型に変換して保存できます。

取り出すときもString型であるため注意してください。

取り出すときは以下のようにするとDateTime型で再び取得取り出すことが出来ます。

string datetimeString = PlayerPrefs.GetString("SAVEDATETIME",awakeDateTime.ToBinary().ToString());

DateTime preawakedatetime = DateTime.FromBinary(Convert.ToInt64(datetimeString));

 

 

以上で終わりなのですが、実際に自分が作ったスクリプトを貼り付けておきます。

変数はフィーリングで汲み取ってもらえればと思います。

 

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


public class RealTimeController : MonoBehaviour
{

// Start is called before the first frame update
void Start()
{
//アプリ起動時の現在時刻の取得
DateTime awakeDateTime = DateTime.Now;
//前回アプリ起動時の時刻をString型で取得(保存していたものを呼び出す)
string datetimeString = PlayerPrefs.GetString("SAVEDATETIME", awakeDateTime.ToBinary().ToString());

//TimeSpanで計算するためにDateTime型に変換
DateTime preawakedatetime = DateTime.FromBinary(Convert.ToInt64(datetimeString));

//現在と前回の時刻の差分を分単位で計算
TimeSpan timespan = awakeDateTime - preawakedatetime;
double timespan0 = timespan.TotalMinutes;
//整数部を抽出
double timespan1 = Math.Truncate(timespan0);
//int型に変換
int timespan2 = (int)timespan1;
//分単位の差分をコインに追加
GameObject.Find("CoinController").GetComponent<CoinController>().AddCoin(timespan2);

//現在時刻を前回アプリ起動時の時刻として保存
PlayerPrefs.SetString("SAVEDATETIME", awakeDateTime.ToBinary().ToString());
}