Unreal Engine 4.26 の時刻、日付回りのメモ (C++/Blueprint)

時刻回りの忘備録です。

# 日付と時刻 (Blueprint)

Blueprint では　`DateTime`　という構造体で日付を管理できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/672e4321-b209-0d9e-3d9d-aa55823dcc15.png)

`Now` ノードで現在時刻を取得でき、`AsDateTime` で文字列に変換できる。`AsDateTime` はローカルタイムでの表示になるけど、UTC表示にする `AsDateTime(From UTC)` という関数もある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/8510aeb1-88f2-d0f6-4097-083e71121aaa.png)

DateTime　構造体を　Break　すれば、ミリ秒の値まで取れる。精度がどのくらいあるかはわからない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/1e70a639-39b1-8700-3684-8725a05a79bb.png)

レベルブループリントに書いて実行すると上のような感じで時刻を表示できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/5221c54f-b007-99af-014e-9c14ee4c309a.png)

今日の日付を返す `Today`（時刻は 0:00 になる）、曜日を返す `GetDay` もある。`GetDay` の返り値は整数で、0が月曜、1が火曜・・・という感じになる。

時刻間の大小比較（＞とか＜＝とか）もできる。

# 時間 (Blueprint)

時刻と時刻の差（時間）は、`Timespan` 構造体で管理する。`DateTime` 間の和や差は　`Timespan` 型になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/80a1fa53-a3ee-a698-44e3-432af357dc35.png)

上のようなイベントグラフで、BeginPlay　からの経過時間を表示できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/e4279053-9525-558c-ae94-692a0027a01e.png)

`Timespan` 構造体もミリ秒まで情報を持っているので、一応ミリ秒単位での計算はできる。精度はよくわからない。さらに　`GetMicroseconds` というノードがあって、マイクロ秒の値が取得できるぽい。精度はそれこそ全くわからないけど・・・

`DateTime` に `Timespan` を加えたり、引いたりすると `DateTime` 型になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/3a8c63a2-71fe-c527-c8ab-b5940e684307.png)

上のグラフでは現在時刻に１秒加えて、その結果を表示している。

# 日付と時刻 (C++)

`FDateTime` 構造体と `FTimespan`　構造体として、Blueprint　とほぼ同様に扱える。

```TEWorker.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TEWorker.generated.h"

UCLASS()
class TOWNEDITORV6_API ATEWorker : public AActor
{
	GENERATED_BODY()
	
public:	
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "MyLibrary")
		FDateTime StartTime;
	UFUNCTION(BlueprintPure, Category = "MyLibrary")
		FTimespan GetPassedTime();

	// Sets default values for this actor's properties
	ATEWorker();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};
```

Actor のサブクラスとして作った　TEWorker クラスのヘッダに上記のようなコードを追加してみる。

```TEWorker.cpp
#include "TEWorker.h"

// Sets default values
ATEWorker::ATEWorker()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void ATEWorker::BeginPlay()
{
	Super::BeginPlay();
	StartTime = FDateTime::Now();
}

FTimespan ATEWorker::GetPassedTime()
{
	return StartTime - FDateTime::Now();
}

// Called every frame
void ATEWorker::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}
```

`GetPassedTime()` は　`BeginPlay()` からの経過時間を計算して返す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/b064d6d2-3579-805f-dd1e-c8b78eced47a.png)

`BWorker` という　Blueprint　クラスを、`TEWorker` クラスを親として作成して、レベル内に配置してから、上のコードを書いてやると、`GetPassedTime` ノードで経過時刻を計算して表示できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/64724e33-ea1b-5261-4808-bcfa9efa4120.png)

当然だけど、`BWorker` をレベル内に配置しないと、`Tick` が呼び出されなくて実行されない。

このくらいで思い出せるでしょう（多分）。