みつまめ杏仁

アンリアルエンジン(UE4)でGUIを作るためにゴニョゴニョしてます。UIデザイナーの皆様の助けになれば幸いです。

スライダーUIを並べて操作してみる 《続き》

前回それなりにサウンド設定ができそうな雰囲気を醸し出すことができました。

そこにリセット用の項目を追加してみます。

f:id:hiyokosabrey:20180218225034p:plain

右端にもオマケでアイコンを追加しています。

 

 前回の記事はこちら。limesode.hatenablog.com

 ↑これをベースにいじっていきます。

 

Blueprint Interface

今回の肝は、タイプの異なるWidgetを並べて操作できるようにする部分になります。そのための準備として、インターフェイスを用意します。

f:id:hiyokosabrey:20180218225616p:plain

とりあえず ”IF_Settings” と名付けました。

f:id:hiyokosabrey:20180218225841p:plain

ダブルクリックして、エディタ右上にある追加ボタンで関数名を4つ追加します。

f:id:hiyokosabrey:20180218230025p:plain

コンパイルして保存したら閉じます。

 

Interfaceを登録

前回作ったスライダーパーツのWidgetを編集します。

エディタをGraphに切り替えて、Class Settings をクリック。

f:id:hiyokosabrey:20180218230621p:plain

Detailsタブに Interface と書かれた項目があるので、そこの Add ボタンを押して、

さきほど用意した IF_Settings をセットします。

f:id:hiyokosabrey:20180218231046p:plain

ここでコンパイルするとエラーがでます。

f:id:hiyokosabrey:20180219094404p:plain

f:id:hiyokosabrey:20180219094801p:plain

同じ名前のカスタムイベントがいるためです。

そこで急いでイベントを入れ替えていきます。

いつものグラフで右クリックしてノードが検索できるやつで探すと出てくるので、つないであったカスタムイベントと入れ替えます。ちょっと見つけにくいけど、Add Event の中にいます。

f:id:hiyokosabrey:20180219093529p:plain

Add Event カテゴリにいるのは、Interfaceで関数に戻り値(Return Value)を設定しなかったのが理由ですが、UE4は戻り値がない関数はイベントとして扱われることがあります。頭に"Event" と付けられていますが、本当の名前には付いていないので名前が被ることになりました。

f:id:hiyokosabrey:20180219095702p:plain

↑この4つのカスタムイベントをいったん削除して付け替えます。 ↓

f:id:hiyokosabrey:20180219095738p:plain

これでコンパイルしてもエラーは出なくなります。

ちなみに、Interfaceで定義した関数はグラフに置けるのは1つだけなので、2つ目を置こうとすると、すでに置いてある場所にフォーカスが移ります。こういった事故を防ぐ仕様がステキですUE4

スライダーの改造をひと段落つけて、新しいWidgetを用意します。

 

テキストだけのWidget

f:id:hiyokosabrey:20180219101029p:plain

キャンバスには、スライダーと同じ大きさとカラーのテキストブロックを一つレイアウトします。

f:id:hiyokosabrey:20180219101225p:plain

is Variable にチェックを付けておきます。

フォーカス切り替えのアニメーションを付けておきます。

f:id:hiyokosabrey:20180219101920g:plain

グラフでスライダー同様にイベントノードにつなぐのですが、先に Interfaceを登録します。

f:id:hiyokosabrey:20180218231046p:plain

コンパイルしてエラーが出ないのを確認したら、Animationの再生ノードをつなぎます。

f:id:hiyokosabrey:20180219102325p:plain

このテキストだけのWidgetも汎用性を高くしたいので、初期設定用の関数を用意しておきます。

f:id:hiyokosabrey:20180219102554p:plain

テキストを受け取って差し替えるだけのシンプルな関数です。

これで完成です。

つぎは前回作った制御用のWidgetを編集します。

 

 

制御用Widget

 作ったテキストだけのWidgetをキャンバスに並べます。

f:id:hiyokosabrey:20180219112246p:plain

 

初期化している関数 を編集します。

まず配列変数周りをなくして、f:id:hiyokosabrey:20180219113427j:plain

テキストだけのWidgetに、ラベルのテキストを渡します。

f:id:hiyokosabrey:20180219112628p:plain

この関数の外にスライダーWidgetの数を保持する変数が待機しているので、そこに今回の項目数を戻り値として渡します。

 配列変数で処理するのをやめたのは、選択項目に別のWidgetが追加になって配列変数が使えなくなったためです。配列変数の型を wd_slider型 から UserWidget型 に変更しても、その配列変数には 1種類の同型のUserWidgetしか格納できませんでした。

2022/7/16 追記>>

あらんさん にご指摘(ブログ下部コメント参照)いただいて調べてみました。

記事を読み返してみて、前回の操作ですでに並べたWd_Slider型のオブジェクトから Promote to variable(変数に昇格) してる箇所があります。それを配列にしてるのでUserWidgetというカテゴリではありますが、VariableTypeが Wd_Slider型の配列になっているので、当然別のWd_TextOnly型が挿さらないわけです。当時の自分にツッコミに行きたい。

というわけで、Promote to variable せずに 新しくVariableTypeが UserWidget型の配列変数をつくるとエラーが出ずに、スルっと追加できます。

← ver4.27のキャプチャ

あらんさん ありがとうございます!

記事を書き直そうかと思ったのですが、差し替える必要のある画像が結構あって、しかも手元にあるUE4系は 4.27しかない状況。4.27でもプロジェクトファイルを開くことができました(この記事執筆時は4.18使用)が、アニメーションの挙動がおかしいのと、微妙にエディタのUIが変更になっているので、改めて UE5 で書き直そうと決意しました。便利なイベントも増えてますし。少し先になりますがなるべく近いうちにUE5版を公開します。

この記事を見つけて試していただいているのに失敗につき合っていただくのは心苦しいのですが、修正範囲が大きいのものあり、動かないわけではないのでこの記事はこのままにします。

<<

f:id:hiyokosabrey:20180219114844p:plain

そこで、前回は wd_slider型のWidgetしかなかったので、配列変数に格納できてそこから数を調べていましたが、今回は直接数を数えて返しています。

f:id:hiyokosabrey:20180219115439p:plain

ちょっと改造の手間を省こうとしてマジックナンバーで対応していますが、

プログラマに渋い顔をされてしまう場合は、親になっているキャンバスやその他パネルで余計なパーツが入らないようにしておけば、下のようなやり方もオススメです。

f:id:hiyokosabrey:20180219115856p:plain

 

ゲームに限らないと思いますが、UIを作るうえでのあるあるのひとつに、あとから項目の数が変更になるのが挙げられるとおもいます。すべてのノードをいつまでも把握しておくのは難しいので、あらかじめヒューマンエラーを起こさないように自動化しておくのはできるだけやっておいた方がいいです。

 

つぎに新しく、UserWidget型の変数をひとつ追加します。

f:id:hiyokosabrey:20180219121226p:plain

前回作った関数 "changeActiveWidget" を大改造します。

f:id:hiyokosabrey:20180219121620j:plain

↑これを ↓このようにします。

f:id:hiyokosabrey:20180219122241p:plain

ActiveWidgetという器(UserWidget型の変数)に、適宜該当するWidgetを入れていきます。

右端のフォーカスするイベントの呼び出しは、Interfaceで定義した関数にしないといけないので、検索して 作ったInterfaceカテゴリ探します。

f:id:hiyokosabrey:20180219122231p:plain

 

これが Interface の持つステキな仕様です。

なかなかピンとこないかもしれないですが、ActiveWidget に何か適当なWidgetが入っている状態だと仮定して、呼び出すための関数ノードをつなぐことができるのです。

普段、関数を呼び出す際には、呼びたい関数を持っていないとつなぐことができませんが、Interface 経由だと、関数を持っていなくても問題にならないのです。

 

あとは、wd_Slider型の ActiveSlider変数でつないでいるところを、入れ替えていきます。

f:id:hiyokosabrey:20180219173330p:plain

f:id:hiyokosabrey:20180219173408p:plain

後はここ↓

f:id:hiyokosabrey:20180219173605p:plain

 入れ替えてコンパイルに問題なければ完成です。

お役御免になった変数を削除します。

f:id:hiyokosabrey:20180219174506p:plain

確認してみましょう。

f:id:hiyokosabrey:20180219175121g:plain

フォーカスがいい感じに切り替われば成功です。

 

仕上げに、リセットのイベントを追加します。

f:id:hiyokosabrey:20180219180239p:plain

フォーカス用Index番号が 3 の時だけ受け付けるようにします。ちょっと雑ですが初期設定の関数をそのままつないで初期化として使ってます。

 

完全に初期化するか、変更前に戻すかは、決めておく必要がありますが、丁寧に作るならリセット用の関数を用意しておくと後から融通を効かせられます。スライダーWidgetの方にも指定した値に変更する関数があった方が便利です。

 

Index番号で判定する方法については、あとから項目の数が変わったり順番が入れ替わると、きちんと値を変えてやる必要があります。対策の方法はいくつかあると思いますが、今回はこれで。

 

レベルブループリント

リセットのイベントを呼ぶために、Inputノードを追加します。

f:id:hiyokosabrey:20180219181601p:plain

 

動かしてみます。

f:id:hiyokosabrey:20180219182011g:plain

いい感じになってきました。

 

いろんな種類のWidgetパーツを、InterfaceUserWidget型の変数 を使って、汎用的に処理する方法を紹介してみました。

 

長くなったので今回はこの辺にします。

ではでは ステキな設定初期化ライフを!