#memo

indiedev太郎

ドラッグ中もマウスの位置取得する

https://i.gyazo.com/6c62eb2d249fbd37d993639fa41c9847.gif


Mouse position not updated while dragging - UE4 AnswerHub

UE4、ボタンをクリック中は用意されてる関数じゃマウスの位置が帰ってこない、具体的に実装したいのは、ウインドウのドラッグ移動

フォーラムではマウスポインタアクターを用意してそこから取れとのことだけど、わざわざこのためだけにマウスポインタデザイン変更の余地うまれるの嫌なので、Windows.hのやつつかうと普通にとれる、もちろんWindows専用

.h
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Screen")
static void GetCursorPosWin(FVector2D& pos);

.cpp
void UBlueprintFunctionLibraryCpp1::GetCursorPosWin(FVector2D& pos)
{
	POINT p;
	if (GetCursorPos(&p))
	{
		pos.X = (float)p.x;
		pos.Y = (float)p.y;
	}
}

これをGetViewportScaleで取得したdpスケールで割ると今のゲーム内の単位になる

Widgetの自作パネルについて

Widgetのデザイナーでは初めから用意されてるパーツの他に、自分で作ったものも置ける
一番下のタブのUserCreatedがそれで、というかこれはWidgetである
自分でWidgetを作ると勝手にここから参照できるようになっていて、複雑な構造のWidgetを個別に定義しておけばインスタンスみたいな使い方ができる

hud上に表示されるミニウインドウをこれで作ってみる

https://i.gyazo.com/2cb24dc544f2c1278371b1b8d29a02ad.png

実際にゲーム中に描写するWidgetと、ミニウインドウを定義するWidgetを2つ用意する
この時点で、WidgetDesignerのPaletteタブに、自分以外のWidgetが表示されている

ミニウインドウWidgetはこんな感じで普通にWidgetを作る
https://i.gyazo.com/cff85d11e47ff00678029aa02764402a.png
この画像みたいに固定サイズで作るよりは、アンカーを全体にして、全体配置にしておけば、呼び出し側のサイズ変更だけで調節ができるようになる
https://i.gyazo.com/831c09a6f826678645646fecaa637abc.png
その場合は、グラフ右上のパネルから、カスタムサイズを設定するとデザインがしやすくなる

ミニウインドウに例えばボタンがある場合、この発火イベントを呼び出し側でとりたいみたいなとき、そのままではイベントを見ることが出来ない
これは、ミニウインドウのGraphでEventDispoatcherを作成して、それを見たいイベントでcallするようにすると良くなる

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

こうすると、呼び出し側で変数のDetailsを確認するとEvent一覧に今作成したものが確認できるようになる

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

シークエンス変移について、レベル、サブレベルについて、ロード画面について

UE4のシークエンス変移系まとめ

・BPで用意されてる関数は二つあって、一つはOpenLevel、もう一つはLoadStreamLevel

・LevelはどれもPersistentLevelが親、その子としてStreamingLevelを持てる構造をしている、孫はなし

・OpenLevelはPersistentLevelの切り替えで、LoadStreamLevelは現在のLevelが持っているStreamingLevelのロード(持っていないStreamLevelを指定しても読み込まれない)

・LevelCをStreamingLevelで持ってるLevelBを、LevelAでStreamingLevelに指定した時、孫階層までは持てないので、LevelB(のPersistentLevel)までしか読み込まれない

・例えばロード画面、現在のUIを生かしたままロードしたいとかなら、OpenLevelを使用すると現在表示してるWidgetが死ぬので、これはLoadStreamLevelでやる

・GameStateを使用すると、OpenLevelを使用しても変数を渡せるので、HUDの管理とかも出来そう


で、シークエンス変移結局どう作るのかがいいかなんだけれど、GameModeの割当がLevel毎で、これをランタイムに変更するのはできない、(もしかしたらできるのかもしれない)
だからゲームモード変わる部分では、OpenLevelでレベルを切り替えるのが良さそう

多分全部を同じゲームモード、同じレベルで作ることは可能なんだけれど、何もかもがごちゃごちゃしてくるのが予想できる
で、ゲームモード変わる部分ってそもそも何だなんだけど、タイトル画面とインゲームはなんか別っぽいなみたいな雑な感じで作る

でかいレベル読み込みは、時間かかって操作固まってしまうのも予想できるので、ローディング画面を出したい
OpenLevelにはCompleteノードがなくて、LoadStreamLevelにはある
なので、Openするレベルの構造は、パーシスタントレベルは空にして指定したStreamレベルをロードさせるようにする、こうするとOpenLevelした瞬間はLoadingウインドウを表示するようにして、StreamLevelの読み込みが終了したらこれを削除するようにすれば良い
あと読み込みは2段階あって、単純にデータをメモリに展開(同期/非同期)、レベル内に表示/非表示、どこでロード終了扱いにするかは好きにする

https://i.gyazo.com/33ce8915b1a091b266e17ff4ff3c7706.png


お役立ちリンクとりあえず
Loading Screen - Epic Wiki
[UE4] レベルストリーミングについて | historia Inc - 株式会社ヒストリア

Widgetに自動でフォーカス当てる

https://i.gyazo.com/0cae166eae12c8438e3a1924e01a8a74.gif
マウス(ホバー)イベント、ウィジェットを生成して表示しただけでは最初発火しなくて、1回画面内どっかクリックすると発火するようになる、レベルのBeginPlayにWidget生成を挿しただけの状態がgifです

https://i.gyazo.com/5960bb81cb2ff977a093c3b70943027d.png

Widget生成のあと、PlayerControllerに対してfocusを設定してあげると、1回どっかクリックの手間がなくなる

バージョン取得する

.h
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Project")
static void GetProjectVersion(FString& Version);

.cpp
void UBlueprintFunctionLibraryCpp1::GetProjectVersion(FString& Version)
{
	GConfig->GetString(
		TEXT("/Script/EngineSettings.GeneralProjectSettings"),
		TEXT("ProjectVersion"),
		Version,
		GGameIni
	);
}

ESCでゲーム終了しちゃうのなくす

メニューとか実装したりしたらこの機能いらないみたいになることがなくもない

[ProjectFile]\Config
にあるDefaultInput.iniの先頭に以下を追加する

[/Script/Engine.PlayerInput]
-DebugExecBindings=(Key=Escape,Command="CloseEditorViewport")

DefaultInput.iniがない場合は自分でつくるか、ProjectSettingsでInputを適当に追加するとファイルが生成される

参考
During Play in editor (PIE), is there a shortcut to simulate ESC without stopping the game? - UE4 AnswerHub

追記 4.16 version

エディタ設定のショートカットより設定できるようになった、従来の方法は動かない

  1. EditorPreferences > General > KeyboardShortcuts より、上記検索バーよりstopと検索
  2. Play World(PIE/SIE) > Stop の Esc バインドを外して保存