【UE4】曜日を取得する(ブループリント、C++)

皆さま、こんにちは。最近は、現実時間とゲーム時間がリンクしたゲームも多く出ており曜日を利用したいシーンもあると思います。今回はUnrealEngineでの、曜日の取得方法を紹介します。

便利な関数が増えているブループリントですが、現時点では曜日を返す関数は用意されていないようです。C言語や他の言語でも利用されている、基準日から計算する方法で曜日を取得します。

ブループリントを利用する

親クラスにActorを持つブループリントクラスを作成します。サンプルでは「GetWeekDay」としました。

作成したActorのブループリントエディタを開きます。

「イベントBeginPlay」に「PrintString」を接続します。

「Today」を配置します。コンピュータのローカル日時を取得する関数です。

「MakeDateTime」を配置します。

デートタイム > DateTime – DateTime 減算(A-B) を追加します。

「Today」 – 「MakeDateTime」 となるように接続します。

減算の結果と「GetDays」を接続します。

演算 > Integer > %(integer) モジュロ(A%B) を追加します。
割り算の余りを求める演算で、エクセル関数のMOD関数と同じです。

1週間は、7日なので7で割った余りを求めます。

「選択する」を追加しモジュロの結果と「index」を接続します。

Option0またはOption1を右クリックし「ピンの種類を変更」をクリックします。

「ワイルドカード」プルダウンから「String」を選択します。

「ピンを追加」をクリックし「月曜日」~「日曜日」と入力します。
※基準日とする1900年1月1日が月曜なのでOptopn0を月曜日とします。

「MakeDateTime」のYearに1900、Monthに1、Dayに1を入力します。
「選択する」の「ReturnValue」と「PrintString」の「InString」を接続します。

作成したActorを配置しプレイします。

左上に「木曜日」と表示されました。

C++クラスを利用する

次は、C++クラスを使い曜日を取得してみます。ブループリントでも取得できていますが、サマータイムに対応したり追加機能を付ける際に、ブループリントだと複雑になってしまいます。そんな時は、C++クラスを利用してブループリントをすっきりさせることができます。

その他、ブループリントでは対応できないロジックを作成したり処理の軽減などC++を利用するメリットは多数あります。

新規追加 > 新規C++クラス クリックします。

ファイル名に「GetWeek」と入力し「クラスを作成」をクリックします。

VisualStudioで追加したソースが表示されます。

GetWeek.h を変数します。

ブループリントから呼び出し可能な関数を作成します。

UFUNCTION(BlueprintCallable, Category = "OriginalFunction")
	static FString getWDay(FDateTime targetDate);

コードの説明

UFUNCTION(BlueprintCallable, Category = “OriginalFunction”)
ブループリントから参照可能な、関数をOriginalFunctionというカテゴリで追加します。
static FString getWDay(FDateTime targetDate);
関数名をgetWDayとし引数:FDateTime(日付型)、戻り値:FString(文字列)とします。

GetWeek.cpp を編集します。

#include <time.h>

FString UGetWeek::getWDay(FDateTime targetDate)
{
	struct tm t;
	t.tm_year = targetDate.GetYear() - 1900;
	t.tm_mon = targetDate.GetMonth() - 1;
	t.tm_mday = targetDate.GetDay();
	t.tm_hour = 0;
	t.tm_min = 0;
	t.tm_sec = 0;
	t.tm_isdst = -1;

	mktime(&t);

	TArray<FString>ret;
	ret = { L"日曜日", L"月曜日",L"火曜日", L"水曜日", L"木曜日", L"金曜日", L"土曜日"};

	return ret[t.tm_wday];
}

コードの説明

#include<time.h>
mktime()を利用するためにtime.hを読み込みます。
struct tm t;
t.tm_year = targetDate.GetYear() – 1900;
t.tm_mon = targetDate.GetMonth() – 1;
t.tm_mday = targetDate.GetDay();
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
t.tm_isdst = -1;

構造体 tm に引数の日付をセットします。
tm_year(年) は、1900年からの経過年数をセットするため引数の現在の年から1900を減算します。
tm_mon(月) は、0から始まるため引数の現在の月から1を減算します。
mktime(&t);
mktime関数を実行すると、1970年1月1日からの経過秒数までを返します。
また、t.tm_wdayが補完されます。※異常時には-1を返します。
TArray ret;
ret = { L”日曜日”, L”月曜日”,L”火曜日”, L”水曜日”, L”木曜日”, L”金曜日”, L”土曜日”};

補完されたtm_wdayは、0:日曜日~6:土曜日となるためretという文字列の配列に日曜日からセットします。
return ret[t.tm_wday];
上でセットした配列から、補完されたtm_wdayを添え字として値を取得し返しています。

なお、要点を明確にするため例外処理やサマータイム対応といった処理は考慮しておりませんので、予めご了承ください。

ブループリントエディタに戻り、作成したC++クラスを検索します。
上記で指定した、OriginalFunctionカテゴリのGetWDayという名前の関数が表示されます。

「GetWDay」の「TargetDate」に「Today」の「ReturnValue」を接続します。
「GetWDay」の「ReturnValue」を新たに設置した「PrintString」に接続します。
※C++クラスで出力しているものと区別のため「PrintString」の「TextColor」を赤に変更しました。

プレイすると赤色で「木曜日」と表示されました。

他にも色々な方法がありますので一例の紹介となります。

diprossではC++によるプラグイン開発を請負っています。

エンジニアリング事業部からの最新情報をお届けします