#memo

indiedev太郎

UE4、#IF DEBUGもどきマクロの作り方

色々やっているとShippingバージョンではやってほしくないノードとかが出てくる、C++の#IF DEBUGはDEBUGバージョンだけ指定コードをコンパイルしてくれる機能で、これと似たようなマクロがあったら便利
今回できるものは本家と違ってBPから除外するわけではないので、実際に処理が軽くなるみたいなのは薄いけど、見た目がわかりやすくなって良い

Configのビルド設定取得する

ビルド設定はDefaultGame.iniに書かれていて、C++でこれを取得する関数を用意すると今のビルド設定が見れる

DefaultGame.iniの

[/Script/UnrealEd.ProjectPackagingSettings]
BuildConfiguration=PPBC_Development

これがビルド設定の部分、エディタのビルド設定は "Debug", "Development", "Shipping" があり、これに対応するのは
"PPBC_DebugGame", "PPBC_Development", "PPBC_Shipping" となる(確認したのはwindowsなのでOSXとかなら変わるかも)

この設定を見る関数をFunctionLibrary辺りに作る

.h
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Configuration")
static void GetBuildConfiguration(FString& Type);
 
.cpp
void UBlueprintFunctionLibraryCpp1::GetBuildConfiguration(FString& Type)
{
	GConfig->GetString(
		TEXT("/Script/UnrealEd.ProjectPackagingSettings"),
		TEXT("BuildConfiguration"),
		Type,
		GGameIni
	);
}
エディタでマクロ組む

あとはエディタのMacroLibraryでこのようなマクロを作成すると、IFDEBUGもどきノードができる

https://embed.gyazo.com/4f36c3e9e3e01c664894a07fc6ec525f.png

SwitchOnStringノードはAdd pinで、文字列と一致した場合はこっちに進むみたいな処理を作れる

UE4、Inputの長押し処理の実装

十字キーでインベントリのリストを送るみたいな処理、長押しのときはループでやってほしい
これを作るためには、Inputの長押し判定を作る必要がある

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

PlayerControllerのGetInputKeyTimeDown()関数にKey構造体を渡すとそのボタンが何秒押されているかを返してくれる、リリースのたびに0に戻る
LongPressThresholdで指定した秒数以上長押ししているとループ内の関数が実行される、右端のDelayがループ間隔になる

マクロにするとこんな感じ

https://i.gyazo.com/6ae17a368976c3339d3bba66aa1ffe6b.png

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