UMGでのキー入力イベントをC++で書く[UUserWidget::NativeOnKeyDown]
はじめに
UMGでは普通のブループリントで実装できるようなインプットキーイベントが受け取れません👇
そこで、ウィジェットブループリント内でOnKeyDown
関数(場合によってはOnPreviewKeyDown
関数)をオーバーライドして実装することで、キー入力を受け取ることができるようになります。
これについては以下の方の記事を参考にしてください。
ただ、欲しい入力イベントを全部実装していたら結構ノードつなぐのしんどいですよね...
そこでこれらをC++で実装してしまい、それを継承したウィジェットブループリントを作ればかなり楽できそうですね。
それでは実際にやっていきます。
UUserWidget継承のC++クラス作成
UUserWidget
をベースにC++クラスを作成します。
ここにOnKeyDown
関数を実装すればよいのですが、なんと、C++ではOnKeyDown
関数をoverrideできません。
エンジンソースのUserWidget.h
をのぞいてみると...
それもそのはず、BlueprintImplementable
なだけでvirtual
がついていません。
そしてもちろんC++では、virtual
キーワードがない関数をoverrideできません。
どうすればいいか。
UserWidget.h
の1250行目あたりを見てみると...
virtual
ついてるやついっぱいあるやん!!
プレフィックスにNative-
がある同様の関数がたくさんありますね!
どうやらこれを使えば良さそうです。
ただこれを使うには[プロジェクト名].Build.csにて"Slate"
と"SlateCore"
モジュールを有効化してあげる必要があります。
SlateとSlateCoreの有効化
早速[プロジェクト名].Build.csに行って、有効化しましょう。
👆これを、こう👇
ここに関しては公式のドキュメントにも詳しく書かれています。
UMGでもスレートの一部を使ってるからなんでしょうかね、スレートを有効にしないといけないっぽいです。
無事モジュールが有効化できたら先ほど作ったC++クラスに処理を書いていきます。
NativeOnKeyDownのoverride実装
まずはヘッダーでoverrideする関数の宣言と、特定のキーで呼び出す関数を作成します。 今回はWASDとTABだけにしておきます。
呼び出す処理はBlueprintで実装できるようBlueprintImplementableEvent
にしておくとよいかと思います。
続いてcppファイルです。
Blueprint上でOnKeyDown
関数を実装するのと同じようにやっていきます。
ちなみにFReply::Handled
とFReply::Unhandled
関数はstaticな関数なのでFReply
をインスタンス化しなくても呼び出せます。
ではこれを継承したウィジェットブループリントを作って今実装したものを使ってみましょう。
Widget Blueprintの作成と実装
C++クラスを継承してウィジェットブループリントを作成します。
このとき、C++クラスを右クリックして"Create C++ class derived from..."を選択してしまうと普通のBPエディターが開いてしまうので、WidgetBlueprintを作ってから親を変えます。
リペアレント👇
リペアレント後は以下のように先ほどC++で宣言した関数を実装することができます。
ではこのWidgetを表示してみましょう。
ちゃんと実行されていますね👇
※ちなみに(Native)OnKeyDownを使うときは、対象のWidgetにフォーカスがなければいけないのと、InputModeUIOnly(またはUI and Game)が有効でなければならないので、そこを忘れずに。