関連ブログ
- [UE4][UE5]開発環境の容量を少しでも減らす 2024.08.14UE
- [UE5] PushModel型のReplicationを使い、ネットワーク最適化を図る 2024.05.29UE
- [UE5]マテリアルでメッシュをスケールする方法 2024.01.17UE
CATEGORY
2018.02.16UE4UE/ UMG
今回はUMGのNavigation機能について解説していきます。
この機能を使うと入力処理を書かずにキーボード・ゲームパッド操作に対応できます。
クリック操作も生きるのでPC向けのゲームのように複数の操作に対応できます。
①Widgetを配置
※今回はButtonWidgetを使用します。
②IsFocusableにチェックが入っていることを確認
③初期カーソルが合うボタンをSetKeyboardFocusで設定
※Constructイベントではうまくフォーカスしないので表示するイベントを作って呼ぶようにして下さい。
④UIの入力設定
Navigationの項目で上下左右・前後を設定します。
上下左右はキーボードの上下左右、ゲームパッドのアナログスティック、上下左右キー
前後はTabとShift+Tabでの操作になります。
とりあえずはEscapeでOKです。
⑤フォーカスがわかる点線の表示・非表示設定
プロジェクトの設定→User Interface→Focus→RenderFocusRuleを変更
Always 常に表示
Non Pointer マウスカーソルが別なWidgetをクリックした場合消えます。
Navigation Only Widgetにフォーカスが移動した時表示
Never 常に非表示
⑥Widgetを作成し入力を受け付けるようにします。
ゲーム中の入力を無効にしたい場合は「SetInputModeUIOnly」
ゲーム中の入力をそのまま有効にしてUIを操作したい場合は「SetInputModeGameAndUI」を設定して下さい。
クリックイベントにも対応
一部のWidgetはクリックイベント(OnClicked)に対応しています。(ボタン、チェックボックス等)
スペースバーとエンターキー、コントローラーのAボタン(EKeys::Gamepad_FaceButton_Bottom)でボタンをクリックできます。
注意する点としては、独自に作ったWidgetではクリックイベントは対応してません。
OnKeyDownをオーバーライドして 独自で実装する必要があります。
うまくいかないときチェックするべき点
これは何らかのアプリ側の仕様をきめて独自に実装する必要があります。
例として…
TickですべてのボタンのHasKeyboardFocusを確認してすべてのフォーカス外れていることを検知したら、
先頭のボタンをSetKeyboardFocusしてフォーカスを戻してあげる処理を用意してあげると良いかと思います。
ゲームらしいUIを作りたい人はアニメーションを使いたくなる人もいるかと思います。
その場合はフォーカスイベントを使用するとフォーカスされたタイミング、外れたタイミングで処理を行えます。
フォーカス時
OnAddedToFocusPath
フォーカスが外れた時
OnRemoveFromFocusPath
OnFocusLost
デフォルトの操作じゃぁ満足できないあなた!!
C++プロジェクトであれば、変更可能です。
やり方は簡単、NavigationConfigを継承して独自のNavigationConfigを用意しFSlateApplicationに設定するだけ
エンジンコード変更する必要なし!!
プロジェクトのModuleRuleに「Slate」を追加
XXX.Build.cs
1 |
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "Slate" }); |
独自のNavigationConfigのヘッダーファイル
1 |
#include "NavigationConfig.h" |
class UMGTEST_API FCustomNavigationConfig : public FNavigationConfig
{
public:
FCustomNavigationConfig();
virtual ~FCustomNavigationConfig();
};
Cpp
1 |
#include "NavigationConfig.h" |
FCustomNavigationConfig::FCustomNavigationConfig():
FNavigationConfig()
{
// デフォルトのキーイベントを無効にしたい場合はEmptyで初期化をしてください。※アナログスティックの入力は無くならないです。
//KeyEventRules.Empty();
// WASDのキーを追加
KeyEventRules.Emplace(EKeys::A, EUINavigation::Left);
KeyEventRules.Emplace(EKeys::D, EUINavigation::Right);
KeyEventRules.Emplace(EKeys::W, EUINavigation::Up);
KeyEventRules.Emplace(EKeys::S, EUINavigation::Down);
}
独自のFNavigationConfigをFSlateApplicationに設定します。
※一度初期化すれば問題ないので、今回はGameInstanceのInit関数で初期化します。
1 2 3 |
void UMyGameInstance::Init() { Super::Init(); |
FSlateApplication::Get().SetNavigationConfigFactory([] { return MakeShared(); });
}
ソースコードのコメントに書きましたが、KeyEventRules.Empty(); を使っても、アナログスティックでの入力は無くなりません。
どうしても無くしたい場合はGetNavigaitonDirectionFormAnalogInternalをオーバーライドして独自に拡張する必用があります。
もっとNaviagetionの仕組みを拡張したい場合はNavigationConfig.hあたりを参考にしてみると良いかもしれません。