#memo

indiedev太郎

UE4、KillZVolumeの挙動について

KillZVolumeは、触れたアクタの持つFellOutOfWorld()という関数を実行するように言う(これだけの実装)
FellOutOfWorld()はAActorに実装があり

  1. Physicsを切る
  2. ActorHiddenInGameをtrueに
  3. ActorEnableCollisionをfalseに
  4. Destroy()実行

という処理を行う

FellOutOfWorld()はBPでオーバーライドできるようにはなっておらず、C++側でオーバーライドする必要がある

UE4、BPでのデストラクタ処理の作り方

アクタ(AActor継承クラス)がDestroyされたときの流れ

  1. Destroy()呼ばれる
  2. Destroy()の中でDestroyed()呼ばれる
  3. Destroyed()の中でReceiveDestroyed()呼ばれる
  4. Destroyed()の中でOnDestroyed()呼ばれる

BPではReceiveDestroyedOnDestroyedを使用する、これらの関数はC++側には実装はない

ReceiveDestroyed
BlueprintImplementableEventとして定義されているので、BPでオーバーライドして使用する
DisplayName = “Destroyed”となっているので、BPでは"Event Destroyed"ノードとして現れる(C++のDestroyed()とは別)

参考
Unreal Engine | ゲームプレイ要素をブループリントに公開する

OnDestroyed
イベントディスパッチャー(DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam)として定義されていて、BPではバインドして使用する
ReceiveDestroyedとの違いは、DestroyedされたActorがポインタとして返ってくるのでどうこうしたいならこちらを使用する

参考
Unreal Engine | マルチキャスト デリゲート


実行順序は、ReceiveDestroyedのほうが一行だけ先に呼ばれる

https://i.gyazo.com/fdb8fe996a76e190560c43ad147aeccc.png

SVNでリビジョン管理やる

いい加減ソースコントロール使う、SVNが楽そうなのでそれでやる

1.TortoiseSVNのインストールまでやる

2.リポジトリを適当なところに作成する、ここに差分が集まってくる、デフォルトのフォルダ構造作りますかって言われるけど作らないでそのままOK押して終了する

3.プロジェクト作成する

4.プロジェクトフォルダに対してチェックアウトを行う
https://i.gyazo.com/2523ec6ecc21fefd0da98202928c49e8.png

空じゃないんだが?って言われるけどそのままやる

5.差分取るファイルを選択してAddしていく、ドキュメントによるとこれ(チェックついてるやつ)をやる、SourceはC++プロジェクトじゃないとない
https://i.gyazo.com/b25543806c03adcf0045b86fb2a9a53a.png

6.コミットしておく(一番上の階層(プロジェクトフォルダ)でやると1発で全部やってくれる)

7.UE側でsvnに接続する、左上のSourceControlアイコンを押す
https://i.gyazo.com/91c5a39a713e51d7a2a282c008164c8f.png

これでとりあえずできるようになった、エディタからコミットできるのはContentsのものだけなのでC++の編集とかはエクスプローラーから自分でやる(多分)
ラベルは設定してないので空欄だけれど、そもそもラベルの必要性いまいちよく分かってないので、よく分かったら追記します


参考
Unreal Engine | ソース コントロールとして SVN を使用する
TortoiseSVN の基礎勉強 〜TortoiseSVN によるバージョン管理を使う〜 — バージョン管理システム入門(初心者向け)
UE4 ソースコントロールを使ってアセット管理をする - Let's Enjoy Unreal Engine

セーブについて

UE4にはセーブとロード用の関数が用意されている

セーブデータ自体はSaveGameクラスを拡張して定義する、このクラスに作成した変数がファイルに書き込まれる
SaveGameクラス自体はUObjectを継承しているだけで全く実装はなく、セーブ系の関数を使う時にこのクラスを継承しているかどうかを見ているだけ
C++で書いても、UPROPETYで公開できるようなものしかセーブされないので、例えばTMapで所持アイテムを管理しているとかなら、ロード時にパースする処理が必要

参考
Unreal Engine | ゲームを保存する
Unreal Engine | ゲームをブループリントで保存する
Unreal Engine | ゲームを C++ で保存する

翻訳について

ローカライゼーションダッシュボードを使ってテキストをローカライズする。 - Qiita

FTextを検索して置換することができる、なのでHUDに出てくる文字は全てをFTextでやっておく、むしろ置換対象に出てくるのでこれ以外では使わない

https://i.gyazo.com/11ebdf0b9918bf19d22c6360d9234501.png

こんな構造体を使用するDataTableから全抽出してくれて便利


参考
Unreal Engine | FText

UE4.13、C++側で構造体を定義してBPで使う

USTRUCT(BlueprintType)
struct FGameItem
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
	FName key;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
	int32 num;

	// Constructer
	FGameItem()
	{
		key = FName(TEXT("none"));
		num = 0;
	}
	FGameItem(const FName InKey, const int32 InNum)
	{
		key = InKey;
		num = InNum;
	}

	// Functions
	int32 GetNum() const
	{
		return num;
	}
	int32 AddNum(int32 InNum)
	{
		return num += InNum;
	}

	int32 SubNum(int32 InNum)
	{
		return num -= InNum;
	}
};

これでエディタで構造体を作ったときのように、BPで構造体型の変数が作れたり、breakノードが使えるようになる
https://i.gyazo.com/cfe95af85a2eff643e795d4233f8a972.png

・コンストラクタでデフォルト値を設定する
・UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Category") を設定したメンバ変数がbreakで展開される
・UFUNCTIONマクロは使えない(多分)


上記SS内のTMapでこの構造体を管理して、値をBPでみたいというコード、ついで

public:
	// Player ItemList
	typedef TMap<FName, TSharedPtr<FGameItem>> ItemMap;
	ItemMap ItemList;

	UFUNCTION(BlueprintCallable, Category = "Item")
	bool GetItem(const FName InKey, FGameItem& Item)
	{
		if (ItemList.Contains(InKey))
		{
			Item = *ItemList[InKey];
			return true;
		}

		return false;
	}

参考
Structs, USTRUCTS(), They're Awesome - Epic Wiki

Rama is God.

4.13のレンダーターゲットへのブループリント描画

4.13の新機能、テクスチャのUV座標を取得と、レンダーターゲットへのブループリント描画を触っておく

Unreal Engine 4.13 Released!


テクスチャのUV座標取得
関数FindCollisionUVがそれ、実装はGameplayStatic.cppにある
エンジン設定でbSupportUVFromHitResultsを有効にすると使えるようになる、これを有効にするとメモリ負荷が増える
Linetrace結果のHit構造体を引数にとって、Hit先のコリジョンを取得し、HitPointのUV座標を計算する

ノードはこんなかんじ、UVChannelは設定を特にいじってなければ0が通常のテクスチャUV、1はライトマップ用になっているはず
https://i.gyazo.com/313e9fda3f3359622fb21b54d7a5971c.png

参考
UBodySetup | Unreal Engine API Reference


レンダーターゲットへのブループリント描画
レンダーターゲットはそもそも何かで、今までのバージョンでは、例えば監視カメラがあったとして、それが写している映像をマップ内のモニタに表示させたい、みたいなときに(のみ)使用されていたリアルタイム生成テクスチャ、のような感じであった

今回のアップデートで追加されたこの機能は、カメラの映像を反映させるだけでなく、ユーザー側から結構自由にレンダーターゲットをいじれるようになる機能で、上記のUV座標取得と組み合わせることで、例えば板ポリに直接お絵かきとか可能になる

レンダーターゲット描写の関数は色々あり、順に確認する

DrawMaterialToRenderTarget
指定したレンダーターゲットに指定したマテリアルを描写する
マテリアルのemissiveとOpacityアウトプットのみが描写されるので、それ用に作る
また内部的にはCanvasを利用してるので、UI用マテリアルでも動く

この関数ではただマテリアルを転写して終わりなので、色々やるようの方を確認する

BeginDrawCanvasToRenderTarget / EndDrawCanvasToRenderTarget
https://i.gyazo.com/22fdb4551c23a387531d960670e20e2d.gif

https://i.gyazo.com/562cbe3d5efeef289399be13059d33e2.png

BeginDrawCanvasToRenderTargetでは、レンダーターゲットのサイズのCanvasを生成する、そのCanvasに対し、Canvas描写系の関数を実行し、EndDrawCanvasToRenderTargetでCanvasをレンダーターゲットに反映するという流れ

このときに、上記のUV座標取得と組み合わせることで、任意の位置への描写が可能になる

どれも実装はKismetRenderingLibrary.cppにある

参考
UCanvas | Unreal Engine API Reference

できること
https://i.gyazo.com/becb396b350b06aa506c1010400d4891.gif

Time値を渡してやると色々できそう、機能紹介の波紋のノードの解説あるのかな
例えばTimeを使いたいとき、TextureRenderTargetのHDRのチェックを外していると、1以上の値が切り捨てられているので動かなくなる、逆に通常の範囲内での使用ならこのチェックは外していい