みつまめ杏仁

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

そうだ、UE4でQUIZゲームを作ろう《組み立て編》

続きの記事になります

 

limesode.hatenablog.com

 

 

前回の記事ではクイズゲームに必要な表示を、Widgetブループリントというアセットで用意しました。今回は全部を組み合わせて動くようにします。

 

目次

 

 

その名をQuizGame

仕上げというか材料を入れて煮込む鍋のような存在として、最後のWidgetブループリントを一つ追加します。名前を wb_QuizGame としました。

このWidgetブループリントは、ゲームを動かす要となるアセットになります。

今まで用意してきたものはパーツです。

f:id:hiyokosabrey:20210519013532p:plain

さっそくキャンバスに、用意したWidgetを置いていきます。

まずは背景から。

 

Paletteタブ の User Created カテゴリに 作ったWidgetたちが並んでいます。

ここから wb_BG をキャンバスにドロップします。

f:id:hiyokosabrey:20210519014726p:plain

こうやって、Widgetアセットは他のWidgetでも再利用できたりします。

最近Web界隈?で話題のアトミックデザインというやつが、UE4でも扱うことができます。ゲームUIの開発では修正や調整の効率化のためにいろいろ試行錯誤はしていて、『アセット開発』などという言葉が出てきたあたりから本格化した印象ですね。

 

 余談はさておき

サイズがおかしいのでアンカーの設定を変更して拡げてやります。

f:id:hiyokosabrey:20210519234844p:plain

画面いっぱいにします。

f:id:hiyokosabrey:20210519235016p:plain

 

次に、Widget Switcher を取り出します。
Paletteタブ の Panelカテゴリにあります。

f:id:hiyokosabrey:20210519235412p:plain

この Widget Switcher が事前に用意しておいた Widgetたちの器になります。

これも、上の背景(wb_BG)同様にアンカーで画面いっぱいまで拡げます。

 

まだ中身が無いので入れていきます。

f:id:hiyokosabrey:20210519235016p:plain

 

Button の中に Text を入れたように ぽいぽいっとドロップします。

ただし順番が大事なので、今回は以下のように決めました。

 

 ① wb_Title (タイトル画面)
 ② wb_Main(クイズ画面)
 ③ wb_Right(正解演出)
 ④ wb_Wrong(誤答演出)

 

f:id:hiyokosabrey:20210520002035p:plain

WidgetSwitcher が表示するのは常に1つ。それを番号で管理します。

そのために登録順が重要になってくるのです。

タイトル画面が表示されていればバッチリです。

 

WidgetSwitcher を選択した状態で Detailsタブ を見てみましょう。

Switcher というカテゴリに Active Widget Index というパラメータがあります。

f:id:hiyokosabrey:20210520003201p:plain

ここを 0~3 の数字で変更してみてください。

数字を入力してEnterキーを押すと切り替わるのがわかります。

確認が済んだらタイトル画面からゲームを始めたいので 0 に戻しておきます。

 

ちょっと慣れないといけないのですが

プログラミングの世界では、番号を振って管理するものはたいてい

ゼロ始まり です。ゼロ番からナンバリングします。

なので、

 ① wb_Title (タイトル画面) → Index = 0
 ② wb_Main(クイズ画面) → Index = 1
 ③ wb_Right(正解演出) → Index = 2
 ④ wb_Wrong(誤答演出) → Index = 3

となっています。

 

ここでレイアウト作業は終了です。編集モードを Graph に変えましょう。

f:id:hiyokosabrey:20210520004016p:plain

Designerモード同様に、エディタ左にあるリストから取り出します。

まずVariables タブから  WidgetSwitcher を探してグラフにドロップします。

f:id:hiyokosabrey:20210520010703p:plain

ドロップする際に、ちいさなポップアップが出るので、Get~ の方を選びます。

f:id:hiyokosabrey:20210520011115g:plain

これが、『Getノード』のカタチです

このノードの右にある青い◎からドラッグします。

指を離したところでコンテキストメニューが出てくるので、上の検索フォームから  active と入力します。

リアルタイムにフィルタリングされるので、

Set Active Widget Index を探して選択します。

f:id:hiyokosabrey:20210520012813g:plain

これで、「WidgetSwitcher に対して、Active Widget Index の値をセットするよ」 という意味のつなぎ方ができました。

この方法だと、関連のある候補から選ぶことになるので、無関係なものをつないでエラーといった事態が避けられます。ぼくがブループリントをオススメするポイントの一つです。

この仕様は、ドラッグして指を離した際のポップアップにあるチェックボックスで切り替えができます。Context Sensitive(文脈依存)のスイッチです。

f:id:hiyokosabrey:20210520222750p:plain

ここは有効のままにしておくのをオススメします。

 

このノードを、最初から並んでいる赤いノードにつないでみましょう。

f:id:hiyokosabrey:20210520223120p:plain

ブループリントは同じ色の 〇同士をつなぐのが基本になります。

そして、白いホームベースの形同士をつないでようやくノードからノードへ処理の流れができあがります。

この赤い Event Pre Construction ノートは特殊なノードで、コンパイルしたときに実行されるイベントになります。

 

試しに、上の画像のように、Indexの値を 0以外 に変えて、エディタを Designer モードに切り替えたら、コンパイルしてみましょう。

f:id:hiyokosabrey:20210520223955p:plain

WidgetSwitcherの表示が変わります。

f:id:hiyokosabrey:20210520223946p:plain

WidgetSwitcherの切り替え方法をなんとなく実感できたところで、編集中断。いったん保存します。

 

 

タイトル画面からの遷移

次に、タイトル画面のWidgetブループリントを編集します。

f:id:hiyokosabrey:20210520230318p:plain

ボタンをクリックしたときの挙動を作っていきます。

 

まずキャンバスに置いた Button を選択します。

f:id:hiyokosabrey:20210520230519p:plain

 

エディタ右側 Detailsタブをスクロールした最下段にある、緑のボタン On Clicked をクリックします。

f:id:hiyokosabrey:20210520230824p:plain

するとすぐさまエディタGraphモードに切り替わります。

 

f:id:hiyokosabrey:20210520231049p:plain

新しくイベントノードが現れました。

これはクリックした際に呼び出されて実行されるイベントノードです。

カッコの中は配置した Button の名前です。Designer モードでいつでも変更できますが、今回は一つしかレイアウトしていないので、命名についてはひとまず放置します。

 

つぎにイベントディスパッチャーを作ってこのイベントにつなぎます。

エディタ左側から Event Dispatchers を探して、右にある + ボタンをクリックします。

f:id:hiyokosabrey:20210520232544g:plain

ED_OnClicked と リネームしました。
これを、右のグラフにドラッグ&ドロップします。

指を離すと小さなポップアップが出るので、Call を選択します。

f:id:hiyokosabrey:20210520233017g:plain

これを、On Clicked の赤いイベントノードとつなぎます。

f:id:hiyokosabrey:20210520233223p:plain

これでクリックしたことを通知する仕組みが準備できました。

コンパイルして保存します。

 

QuizGameのWidgetを編集再開です。

f:id:hiyokosabrey:20210520233701p:plain

先ほどの接続を切ります。

白い5角形を右クリックして Breake~ を選択するか、

白いラインの上で、Alt キーを押しながらクリックしても切断できます。

f:id:hiyokosabrey:20210520234619p:plain

 

 

切れたら、エディタ左側に Variables というリストがあります。

そこに WidgetSwitcherに仕込んだWidgetたちが並んでいるので、さきほどイベントディスパッチャーを追加した wb_Title をグラフに取り出します。タイプは Get で。

f:id:hiyokosabrey:20210520234329p:plain

ノードの右にある〇(出力ピン といいます)からドラッグしてノードを検索します。

今度は、 bind と入力。

f:id:hiyokosabrey:20210520235548g:plain

そして、 Default > Bind Event to ED On Clicked を見つけて選択。

ここ似たようなやつが多いので慎重に。

このバインドノードと 赤い Event Pre Construction をつなぎます。

f:id:hiyokosabrey:20210521000011p:plain

 

つぎに、バインドノードの左下にある、□ Event からドラッグしてカスタムイベントノードを取り出します。Add Custom Event を選択。

f:id:hiyokosabrey:20210521001754g:plain

UE4は結構な数のイベントノードがあらかじめ用意されていますが、このカスタムイベントは、イベント処理を自由に作ることができる大変便利なノードです。

スタートボタンを押したときのふるまいをつくったので、PressStartButton と命名しました。

 

ノードの並びをちょっと整理しました。

WidgetSwitcher を切り替える Set Active Widget Index ノードの Index を 1 にします。

f:id:hiyokosabrey:20210521002442p:plain

そろそろプレビューして確認してみます。

コンパイルして保存します。

 

 

確認してみる

実際に動くかどうか確認するには、再生する必要があります。

メインウィンドウのPlayボタンを押すか Altキーを押しながら P キーで今のレベル(見えている状態のワールド)がゲームプレイ状態になります。

f:id:hiyokosabrey:20210521003245p:plain

今はまだ何も起こらないので、Widgetを表示できるようにします。

 

レベルブループリントを編集します。

メインウィンドウの上部にある Blueprints というボタンをクリックすると、プルダウンリストが出てくるので、 Open Level Blueprint を選択します。

f:id:hiyokosabrey:20210521004220p:plain

 グラフエディタが開きます。

f:id:hiyokosabrey:20210522005051p:plain

新しくノードを取り出します。

何もないところで右クリックして Create widget を検索。

f:id:hiyokosabrey:20210522005435p:plain

 

出てきたのはこんなノード ↓

f:id:hiyokosabrey:20210522005541p:plain

Class のところに wb_QuizGame をセットします。

 

セットする方法は2種類。

プルダウンから検索する方法と、コンテンツブラウザでアセットを選択した状態で白い矢印をクリックする方法。

f:id:hiyokosabrey:20210522010338p:plain

Return Value のピンからドラッグして、Add to Viewport ノードを取り出します。

f:id:hiyokosabrey:20210522011134p:plain


初めから置いてある Event BeginPlay ノードとつなぎます。

f:id:hiyokosabrey:20210522011148p:plain

これで準備完了、ではあるのですが、少しだけ安全対策を施しておこうと思います。

UE4 は UI のクリック対象ではない部分(例えばボタン以外)をクリックしてしまうと、背後のステージをクリックしたことになって、カメラをぐりぐり動かすことができるようになっています。そして、マウスカーソルが非表示にされてしまいます。フォーカスが移ってしまうんですね。
Shiftキー を押しながら F1 キーで戻ってきますが、慣れないと焦るので、今回はUI表示がメインの画面でもあるので、常時カーソルを表示するようにしてしまいましょう。

ノードを2つほど取り出してつなぐだけです。

 

まず何もないところをクリックして、Get Player Controller ノードを探します。

f:id:hiyokosabrey:20210523224029p:plain

f:id:hiyokosabrey:20210523224201p:plain

UE4触ってると、何かとお世話になるやつです。

次に ReturnValue から Set Show Mouse Cursor という変数を 取り出します。

f:id:hiyokosabrey:20210523224414p:plain

f:id:hiyokosabrey:20210523224940p:plain

いつもと様子の違うのが出てきました。

これは、 Player Contoroller が持っている変数に値を書き込もうとしています。

チェックをつけてつなぎます。

f:id:hiyokosabrey:20210523224821p:plain

これで安心。

 

コンパイルして保存します。保存は初めてになると思うので、以下のようなダイアログが出てきます。

とりあえず Widgetフォルダと同じ階層に名前を付けて保存します。

f:id:hiyokosabrey:20210522011617p:plain

 

 

保存できたら再生してみます。

 

f:id:hiyokosabrey:20210522013746p:plain

STARTボタンをクリックして切り替われば・・・

f:id:hiyokosabrey:20210522013810p:plain

バッチリです。

止めるのは Escキー か、 エディタ上部の Stopボタンです。

 

今回プロジェクトを新しく作っているので、UE4を起動すると基本の テンプレートレベルが開かれます。

引き続きこのレベルを使う場合は、毎回ダブルクリックして開くことになります。

最初から開いていてほしい場合は、Editメニューの Project Settings > Maps & Modes にある Default Maps で起動時のレベルを指定できます。

f:id:hiyokosabrey:20210522013623p:plain

 

 結構長くなってきた。

 

流れをまとめると

マウスのクリックを受け付けるWidget に イベントディスパッチャーを追加

ボタンをクリックした際に、イベントディスパッチャーを呼び出す(Call)ことにする

親のWidget は、 マウスのクリックを受け付けるWidgetに対して バインド(紐づけ)をする

イベントディスパッチャーが呼ばれた(Call)ら、バインドしている親Widgetに通知が行って、つながっているカスタムイベントを処理する

 

ことになります。

f:id:hiyokosabrey:20210522104943p:plain

 

イベントディスパッチャーは、バインドしてつながっている相手にだけ通知が渡ります。

自分からはバインドできません。される側になります。

なので、仕事の責任範囲が小さくできるぶん、作りが気楽にできます。

なんかあったらイベントディスパッチャー呼んどくか。あとは知らん。てな具合です。

他にも、

まだ親のほうで処理はつくられてないけど、将来的に必要って聞いてるから、イベントディスパッチャーを呼ぶとこを追加しておこう。というようなゆるい作りが可能です。

 

複数人で開発してる場合、

このタイトル画面Widgetのような場合、ボタンクリックとイベントディスパッチャー呼び出しのところを触らなければ、あとはお好きにどうぞ、とデザイナーにぶん投げることができます。ボタンの仕組みを変えたとしても、最終的にクリックした際にイベントディスパッチャーさえ呼ばれれば、あとは親が何とかします。または、この仮組みのようなWidgetをサクッと作ってプログラマに渡しておくと、ゲーム開発がスムーズになるのを少しは期待できます。

 

さてさて

WidgetSwitcherの切り替えもうまくいってるので、今度はメインの出題画面を仕上げます。

 

 

クイズの出題と回答ボタン

今回はチュートリアルということで、出題は固定の1問とします。

メインのWidgetを編集します。

f:id:hiyokosabrey:20210522114426p:plain

 

Designerモードにしたら、出題用の Text を選択します。

そして右上にある Is Variable を有効にします。

f:id:hiyokosabrey:20210522123302p:plain

最初から Is Variable が有効になっているものもありますが、Text については 無効になっているのが基本なので、必要に応じて チェックを付けます。

ついでに TextBlock_0 を TextBlock_Question にリネームしました。

f:id:hiyokosabrey:20210522123211p:plain

 

Is Variable の状態は

Graphモードに変えるとどう変わったか判明します。

f:id:hiyokosabrey:20210522142000p:plain

Is Variable を有効にすると言葉の通り、

Variables(変数)として扱うことができるようになります。

 

これを グラフに取り出します。Getタイプで。

そこへ、ドラッグして SetText(Text) ノードを探してやります。

f:id:hiyokosabrey:20210522142350p:plain

f:id:hiyokosabrey:20210522142550p:plain

この In Text ピンのところにテキストを入力できるので、問題文を入力してみます。

複数行にしたい場合はShiftキーを押しながらEnterキーで改行できます。

問題文を入力出来たら、 Event Construct につなぎます。

f:id:hiyokosabrey:20210522151814p:plain

世界三大料理として挙げられる 中華料理 と
フランス料理 あと一つは?

 

Event Pre Construct と違うのは、コンパイルしても実行されない点です。ゲームが再生されたときに実行されます。

コンパイルした後、Designer モードに切り替えても Text Block となったままなのが確認できます。

 

確認のため再生してみましょう。

コンパイルして保存したら、Playボタンを押すか、Alt + P です。

Startボタンをクリックしたらちゃんと反映されてました。

f:id:hiyokosabrey:20210522152533p:plain

 

次に回答ボタンを仕込んでいきます。

まずボタンの名前。

ただ配置しただけで放ってあったので名前を付けます。

そうすることでブループリントで扱う際にわかりやすくなります。

 

リネームの方法は2か所で変更できます。

エディタ左側のヒエラルキー内で右クリックして Rename を選ぶか、 F2キー

f:id:hiyokosabrey:20210522153148p:plain

もう一か所は、Detailsタブの一番上

f:id:hiyokosabrey:20210522153355p:plain

どちらで変更してもOK。

上から順番なのが分かるように、 0 1 2 3 とか A B C D 、1st 2nd 3rd 4th など連続するように名付けます。

続けて、Button の子供にした Text も内容を変更します。

この TextIs Variable を有効にして、Button と同じように順番がわかるように名前を付けます。

 

最終的にヒエラルキーはこうなりました。今回 ABCD を採用。

f:id:hiyokosabrey:20210522154152p:plain

これで、編集モードを  Graphモードに移行します。

 

f:id:hiyokosabrey:20210522154848p:plain

 

反復的な操作が増えてきたので、この辺から省略気味でいきます。

 

Variablesのリストに追加されているので、グラフに Getタイプでドロップしたら、

問題文同様に回答のテキストをセットします。

f:id:hiyokosabrey:20210522155527p:plain

一応再生して確認しておきます。

 

f:id:hiyokosabrey:20210522161005p:plain

よしよし大丈夫そう。

 

次に

回答ボタンを押したときに、反応できるように

OnClickedイベントと、イベントディスパッチャーを用意します。

OnClicked イベントは、 Detailsタブの一番下にある緑のボタンから作ると、編集モードが行ったり来たりして面倒なので、Graphモードで作成することにします。

 

まず Graphモードに切り替えて、Variablesリストにある回答用の Button~ を選択

f:id:hiyokosabrey:20210522161656p:plain

すると、エディタ右側の Detailsタブのところに、緑のボタンが現れるので、ここからも On Clicked イベントを作成することができます。

f:id:hiyokosabrey:20210522162223p:plain

スクロール動作が入りますが、編集モードが切り替わらないので、連続して操作するときにサクサク進んでいい感じです。

ここにイベントディスパッチャーを一つ用意してつなぐのですが、パラメータを追加したイベントディスパッチャーにします。

 

まずは +ボタンを押して追加します。名前を ED_Answer としました。

f:id:hiyokosabrey:20210620111505p:plain

選択状態にしておいて、Details タブにある、Inputs の欄にある+ボタンをクリックします。パラメータの名前を Judgment としました。タイプは Boolean です。

f:id:hiyokosabrey:20210522171635g:plain

このタイミングで、一度コンパイルします。

パラメータを追加したりパラメータ名を変えた場合はエンジン内での情報の更新が必要になるようで、グラフに取り出す前だとスルー出来ますが、取り出してからだと、エラーが出ます。

 

このイベントディスパッチャーをグラフに取り出します。

f:id:hiyokosabrey:20210522163546p:plain

OnClicked イベントにつなぎます。

f:id:hiyokosabrey:20210620112413p:plain


4番目が正解だったので、Judgmentのところのチェックボックス を True にします。

これでボタンをクリックしたときに、正解か不正解かという情報も一緒に伝えることができます。

 

これでこのWidgetブループリントは編集完了です。

コンパイルして保存します。

 

 

バインドそして判定結果へ

またQuizGameのWidgetを編集再開です。

f:id:hiyokosabrey:20210520233701p:plain

 子要素のWidgetに イベントディスパッチャーが追加されたので、バインドする必要が出てきました。

タイトル画面の切り替えと同じようにバインドしてやります。

 

出題画面のWidgetを Variables のリストから探してグラフにドロップします。

f:id:hiyokosabrey:20210522165726p:plain

バインドするイベントディスパッチャーを探します。

f:id:hiyokosabrey:20210620112607p:plain


タイトル画面遷移のバインドノードの次につなぎます。

f:id:hiyokosabrey:20210620112752p:plain

カスタムイベントの名前は Result としました。

自動で、Judgmentのピンが追加されています。

こうやってイベントディスパッチャーから値が送られてくるのです。

 

確認のため、Print String ノードをつないで再生してみましょう。

何もないところで右クリックして検索します。

f:id:hiyokosabrey:20210522173122g:plain

色の違うピン同士はつながらないのですが、キャスト(型変換)ノードを間に挟むことでつながることがあります。

よく利用するキャストは、自動で入れてくれるものが多いので助かります。

 

コンパイルして問題なければ再生してみましょう。

回答ボタンをいろいろ押すと、左上に true と false がどんどん下に向かって表示されます。一定時間が経つと消えます。

 

問題なければ、イベントディスパッチャーはうまく働いているようです。 

グラフに戻ります。

確認が済んだので、PrintStringノードは消して、今度は Branch (ブランチ)ノードをつなぎます。

何もないところで右クリックして、bran で検索すると絞り込めます。

f:id:hiyokosabrey:20210522200530p:plain

カスタムイベントと、つないでやります。

f:id:hiyokosabrey:20210620112924p:plain


ブランチノードは何もないところで B キー を押しながらクリックしても取り出せます。

これは条件によって処理の流れを分岐させるノードです。

右に True と False の実行ピンがあるので、ここに WidgetSwitcher の切り替えを行うノードをつなぎます。

f:id:hiyokosabrey:20210620113046p:plain


Index の値は、 WidgetSwitcherにセットした順番のWidgetを意味します。

 

 ① wb_Title (タイトル画面) → Index = 0
 ② wb_Main(クイズ画面) → Index = 1
 ③ wb_Right(正解演出) → Index = 2
 ④ wb_Wrong(誤答演出) → Index = 3

 

これで確認してみましょう。

コンパイルして再生します。

正解画面と不正解画面がうまく切り替わればバッチリです。

完成まであともう少し!

 

あと解決しなければいけない点は2つ。

  1. アニメーションが再生されない
  2. Nextボタンを押しても反応がない

 

2 はもう何度かやってきたのでイメージできると思います。

問題は 1 ですね

 

 

ブループリントインターフェイス

Widgetブループリントを作ったのと同じように、コンテンツブラウザの何もないところで右クリックして、 Blueprints > Blueprint Interface を選択します。

f:id:hiyokosabrey:20210522202708p:plain

IF_QuizGame と命名

f:id:hiyokosabrey:20210522202948p:plain

ダブルクリックしてエディタを開きます。

f:id:hiyokosabrey:20210522203345p:plain

右上を見てみると、名前を入力してほしくてウズウズしてる様子が伺えます。

f:id:hiyokosabrey:20210522203538p:plain

ブループリントインターフェイスは、関数を登録するところです。

といっても名前だけの。

 

イベントディスパッチャーと少し雰囲気が似ていて、中身がないのだけれど、存在できて、呼び出しも可能。呼ばれても何もしないので何も起こらない。一応存在はしてるので、呼び出す処理は先に用意できるし、エラーが起きない。中身は別の場所でオーバーライドして利用することができる。

なんとも不思議な存在。

 

とりあえず名前を付けてあげましょう。

StartAnim

としておきます。

f:id:hiyokosabrey:20210522204741p:plain

編集作業はそれだけです。

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

 

QuizGameのWidgetに戻ってちょっと確認してみます。

f:id:hiyokosabrey:20210520233701p:plain

 

グラフ上で、StartAnim を検索してみると ありました。

f:id:hiyokosabrey:20210522205204p:plain

さっそく取り出してみます。

f:id:hiyokosabrey:20210522205314p:plain

イベントディスパッチャーの Call タイプと同じ封筒のアイコンが右上についています。

これを 先ほどの ブランチノードで分岐した最後につなぎます。

f:id:hiyokosabrey:20210522205804p:plain

とにかく正解だろうが不正解だろうが、なんかわからないアニメーションを再生してよ、ということになります。

さて、だれに対して? 

 

それっぽい関数ノードは見つかったけど、さすがに対象を決めないと、コンパイルエラーになります。

この場合、 正解または不正解のWidgetブループリントが対象です。

さてどちらか?

 

表示されてる方(アクティブな方)

 

どうやって調べる?

こういう時役に立つのが、 get って検索することです。

きっと WidgetSwitcherに Set Active Widget Index なんてノードがあるんだから、Get なんちゃらもあるはずです。

 

ありました get だけだと 大量に出てきたので、get act とするとビンゴ!

f:id:hiyokosabrey:20210522211253p:plain

今アクティブになってるWidgetを教えてくれるノードです。

f:id:hiyokosabrey:20210522211401p:plain

このReturn Value の青いピンを、StartAnimにつなげばよさそうです。

f:id:hiyokosabrey:20210522211535p:plain

さっそくコンパイルして再生してみましょう。

 

・・・

 

はい。すみません。動くわけないですね。

 

でもコンパイルしてもエラーになりません。名前しかない関数なのに、アクティブなWidgetといっても、 wb_Right 、 wb_Wrong にはまだ StartAnimなんて関数はかけらも存在しないのに。

普通は対象アセットが持ってないものには、アクセスできませんし、そもそもつなぐことすらかなわないのです。

それをひとまずエラーにならずに済ませてしまうのが ブループリントインターフェイスなのです。

 

ちなみに上の間接的なつなぎ方を直接的につなぐとこうなります。

f:id:hiyokosabrey:20210620113222p:plain

これでコンパイルしてもエラーにはなりません。編集の順番を無視できます。

 

直接対象につながずにget Active Widget ノードをオススメしたいのは、処理の流れさえおかしくならなければ、WidgetSwitcher の中身の順番が変わっても関係ない点。

いろんなアセットやブループリント触ってるといちいちIndexがどうなってるかなんて把握できないし、忘れがちなので、こういった「今アクティブなやつ」みたいにフワッとした指示の出し方は結構気楽でいいのです。

 

 

で、そろそろアニメーション再生できるようにするか

ということで、wb_Right と wb_Wrong を編集します。

ついでに、Nextボタンの対策も。

f:id:hiyokosabrey:20210522213613p:plain

どちらも同じ内容なので、wb_Right をベースに書いていきます。

 

編集モードを Graphに切り替えると、 エディタ上部に Class Settings という大きなボタンがあります。

f:id:hiyokosabrey:20210522213943p:plain

これをクリックすると Details タブの内容が変わります。

f:id:hiyokosabrey:20210522214205p:plain

まん中付近に Interface というカテゴリがあるので、そこの Add ボタンを押して、今回用意した ブループリントインターフェイスを選択します。

 

f:id:hiyokosabrey:20210522214456p:plain


と、同時に左のMyBlueprintタブにも Interfaces というカテゴリが出現します。

f:id:hiyokosabrey:20210522214709p:plain


これ、ただのカタログのようなもので、グラフにドラッグできません。

f:id:hiyokosabrey:20210522214829p:plain

なので、オーバーライドします。

すぐ上にある Functions カテゴリの右上に Override というボタンがあるのでクリックすると長いリストが出てきます。

f:id:hiyokosabrey:20210522215212p:plain

その一番下に StartAnimがいるはずです。

選択すると グラフに イベントノードが出現しました。

f:id:hiyokosabrey:20210522215337p:plain

ここに、作っておいたアニメーションを再生させる処理をつなぎます

まず Variables > Animations から IN をGetタイプで取り出して、

f:id:hiyokosabrey:20210522215748p:plain

そこから
Play Animation ノードを探します。

f:id:hiyokosabrey:20210522220013p:plain

イベントとつなげばOK。

f:id:hiyokosabrey:20210522220106p:plain

 

 

あとは、ボタンクリック対応

イベントディスパッチャーを用意します。

タイトル画面の遷移と同じく特にややこしいこともしないので、ED_ButtonPressed とでもしておきましょうか。

f:id:hiyokosabrey:20210522220517p:plain

 On Clicked イベントを取り出して、イベントディスパッチャーとつないだら完成。

 

f:id:hiyokosabrey:20210522220703p:plain


コンパイルして保存したら、不正解用のWidgetも同じ様に仕上げます。

流れを振りかえると

  1. ClassSettings の Interface に Add
  2. Functions の Overrideボタンから StartAnim をノードを取り出す
  3. そこにアニメーションを再生させるようにつなぐ
  4. OnClickedイベントを取り出す
  5. イベントディスパッチャーを追加してつなぐ

です。

 

最後の仕上げ

Nextボタンのバインドをするので、

また QuizGameのWidgetに戻ります。

f:id:hiyokosabrey:20210520233701p:plain

正解、不正解の演出のあとは、再びクイズ出題画面に戻るようにします。

 

さて復習です。これをノーヒントでできるでしょうか?

f:id:hiyokosabrey:20210522222053p:plain

ちょっと離れたところとつながってます。

f:id:hiyokosabrey:20210522224829p:plain

 

ということで非情ながら次に進みます。

バインドした際に実行するカスタムイベントは、形態が同じなら共用できます。

パラメータがついたりして差異が生まれると共用はできなくなります。

f:id:hiyokosabrey:20210522225615p:plain

これで、正解の時も不正解の時もおなじ処理ができます。

ノルマとかのUI表示があれば、別々にしてもいいし、回答ボタンの時のようにBooleanのパラメータを使って分岐させるのもありです。

 

このカスタムイベントに WidgetSwitcher の切り替えをつないだら完成です。

f:id:hiyokosabrey:20210522230204p:plain

Index は 1 にしておきます。

コンパイルして問題なければ保存して再生します。

 

画面遷移が下のようにつながっているのが確認できれば完成です。

f:id:hiyokosabrey:20210522231342p:plain

 

 

youtu.be

 

おつかれさまでした

さすがに長かったですね。このページだけで 12,000文字に届きそうです。

 

まとめ

今回作ったものの仕様

複数の画面レイアウトを、それぞれWidgetブループリントとして作成

WidgetSwitcher を使って切り替えて表示

それぞれのWidgetからの通知はイベントディスパッチャーで受取り

それぞれのWidgetへの指示はブループリントインターフェイスを使用

 

このチュートリアルの効果

基本的なUMGの編集方法がわかる

キャンバスに置いたものをブループリントで扱う方法が学べる

複数の画面を手軽にプレビューできる仕組みが実践できる

各画面ごとに対して、軽いインタラクションを組み込むことができるようになる

・・・

といいな

 

 

最後に

理解範囲もボリュームもいい感じだと思ってるんですけど、いかがでしょうか。

もうしばらくアレンジやら、小ネタとかの記事を公開していくつもりです。

少しでも UE4の UI制作に 興味を持ってもらえたら嬉しいです。

 

 

わかりにくいところや質問、ツッコミ等あれば、このブログのコメント機能かTwitterにてお気軽にどうぞ。

自宅でしかレスできないので反応速度に関しては気長モードでお願いします。

 

ではでは

ステキな UMGライフを!

 

 

そうだ、UE4でQUIZゲームを作ろう《準備編》

UE4で試しに作ってみたらそれっぽいのができたやつ シリーズ第n弾

カウントしていないのでnです。まあいつもの癖です。

とある動画を見ていて、UMGに WidgetSwitcher というのがあって使えそうだなと思ったのと、UMGのチュートリアルの教材にクイズゲームはどうだろうかと以前より構想していたのがきっかけです。

 

とある動画というのはこちら


www.youtube.com

 

AdobeXD での画面遷移はアートボード間を行ったり来たりするのが基本なので、UE4の場合、1枚のアートボードを1つのアセット として扱えば XDで作っているかのようなワークフローが実現できそうな気がします。

なので、今回AdobeXDは使わずに、UE4の UMG を使ってAdobeXDのような感覚で画面作りにチャレンジしてみようかと思います。

XDの持つ快適な操作性はうらやましい限りですけどね。

 

この動画からひらめいたのと、AdobeXDを意識したのもあって、見た目がまんまな感じのものが仕上がりますが、そこは突っ込まないでいただけるとありがたいです。

 

 

画面構成はこうなります。

 

f:id:hiyokosabrey:20210522231342p:plain

 

 

今回の記事でフォーカスを当てたいのが下の2つ。

  • イベントディスパッチャー Event Dispatcher
  • ブループリントインターフェイス Blueprint Interface

 

別々のWidget間での連携プレーを実践するための、ほどよいチュートリアルにしたいなと思っているのですけどどうでしょうね。操作方法についてはなるべく易しく説明したつもりです。UMGに不慣れな方にチャレンジしてもらえると嬉しいです。

 

 

まず作るアセットは 7つ。

  1. バックグラウンド(共通)
  2. タイトル
  3. 出題&回答ボタン
  4. 正解演出
  5. 誤答演出
  6. ブループリントインターフェイス
  7. ゲーム画面

 

表示用のアセットを揃える《準備編》と、ブループリントで動かす《組み立て編》の2部構成で考えています。

いったん最小限の構造が出来上がったら、後日おまけの要素を追加する予定です。

  • 問題を増やせるようにする
  • 背景をにぎやかにする
  • タイマーをつける
  • ノルマを設定する
  • ゲームオーバー画面を作る

 

ではさっそく

 

 

目次

 

 

エディタを起動する

今回使用するUE4のバージョンは 4.26.2 です

f:id:hiyokosabrey:20210523102752p:plain

新規プロジェクトを作るところから書いていこうと思いますが、すでに日常のプロジェクトをお持ちで、わざわざそこまでという方は、Developerフォルダ内でも大丈夫です。

起動ボタンを押して出てくるダイアログ(下の部分)。

f:id:hiyokosabrey:20210515235423p:plain

Game を選んで、 Nextボタンをクリック

 

テンプレートは Blank を選びます。

f:id:hiyokosabrey:20210515235920p:plain

 

次に適当なプロジェクト名をセットして Create Project

f:id:hiyokosabrey:20210516000007p:plain

 

スプラッシュが出て、しばらく待つとエディタが起動します。

f:id:hiyokosabrey:20210516000306p:plain

 

 

フォルダを作る

画面下のコンテンツブラウザ内で右クリックして、フォルダを新しく用意します。

一番上にあります。

f:id:hiyokosabrey:20210516000913p:plain

 

フォルダ名はとりあえず Widgets という名前にしておきます。

f:id:hiyokosabrey:20210516003239p:plain


 ダブルクリックしてこのフォルダ内に入ります。

 

 空っぽだと、以下のような文言が表示されます。

f:id:hiyokosabrey:20210516001957p:plain

 

 

ウィジェットブループリントを作る

UE4において、UI表示を担当する仕組みがUMG(Unreal Motion Graphics)で、アセットのタイプは Widget Blueprint になります。

フォルダを作ったのと同じように右クリックして Widget Blueprint を探します。

今度は一番下の項目の中のさらに一番下にあります。辿りやすい。

f:id:hiyokosabrey:20210516002424p:plain

 適当に wb_BG と名付けました。

f:id:hiyokosabrey:20210516003252p:plain

ダブルクリックして専用のエディタを開きます。

 

 

バックグラウンド編

最初のWidgetは背景専用で作っていきます。

f:id:hiyokosabrey:20210516103627p:plain

 このエディタは、2つの編集モード に切り替えることができます。

右上に並ぶ2つのボタンで、オレンジ色にハイライトされているほうが現在のモードを表しています。

まずはこの Designer モードで 表示したいものを置いていきます。

 

 最初から CanvasPanel が一つだけ置かれた状態で編集を開始します。邪魔だと思えるくらいUMGに慣れるまでは、このCanvasが画面のサイズを表していると思って作業するといいと思います。

 

今回は背景ということで、まず左のPaletteタブから Common カテゴリの Image をドラッグします。

ドロップできる場所は2か所あります。

f:id:hiyokosabrey:20210516105648p:plain

作業の手間が少し変わる程度なので、どちらでもOK。

意味合いとしては、

 

キャンバスにドロップ

 置き場所を探りながら直感的に配置したい

 マウスで感覚的に位置を決めることができる

 

ヒエラルキーにドロップ

 親子関係(階層構造)を気にしながら配置したい

 座標がゼロリセットされた状態で配置される

 

一度配置してしまえば、座標の調整は、Detail(詳細)タブからも行えるので、どちらの方法でも大差ないです。後から親子関係を変えると表示位置が変わるので、調整の手間を惜しむなら、一考してからどちらかを選択するといいかも。

 

さてこの取り出した Imageパーツ のサイズと位置を整えるのですが、アンカー(Anchor)の設定をうまく活用したいと思います。

 

適当にキャンバスにドロップしたらこうなりました。

f:id:hiyokosabrey:20210516114033p:plain


右のDetailsタブにある Slot > Anchors にあるプルダウンをクリックします。

ポップアップウィンドウの中から右下のアイコンを選択します。

f:id:hiyokosabrey:20210516114227p:plain

このとき Ctrl キー 押しながらクリックするとラクチンです。

押さずにクリックすると下の画像のようになります。

f:id:hiyokosabrey:20210516121039p:plain

エディタ右にあるDetail(詳細)タブからパラメータを変更します。

f:id:hiyokosabrey:20210516121234p:plain

Offest ~ と書かれた部分は、選んだアンカータイプによって変化します。

今回は上下左右全てを 画面の端から何ピクセル というアンカーを選んだので、すべてをゼロにすると、画面にピッタリ合うようになります。

f:id:hiyokosabrey:20210516121522p:plain

Ctrl キー押しながら選択すると、このゼロを入力する手間が省けます。

レスポンシブな背景完成!

 

この Image パーツは主に画像をセットして使うことが多いのですが、今回はナシで進めます。シンプルなベタ色の四角として使えます。

 

カラーは Detailsタブの Appearance > Color and Opacity から変更できます。

f:id:hiyokosabrey:20210516135454p:plain

これで編集完了。

アセットを保存します。

エディタ左上のアイコンを Compile ボタン → Save ボタン の順でクリックすれば保存できます。

f:id:hiyokosabrey:20210516140803g:plain

ここでのコンパイルの実行は、実際に使える状態に仕上げるというイメージで捉えるとよいかと思います。

何か問題があると警告してくれます。

 

Saveが完了すると、アセット名の横についた * が消えます。

f:id:hiyokosabrey:20210516142804p:plain

保存したかどうかは、↑このタブと、

↓コンテンツブラウザでも確認できます。

f:id:hiyokosabrey:20210516143004p:plain

 

ちなみに

少しでも変化が生じると、コンパイルボタンに? のアイコンが付きます。

触ったかどうかの確認にもなりますが、変更して元に戻しても、?のアイコンは元に戻ってくれません。

放置していても、エディタ終了時に、Saveしてないけどええのん? というダイアログでビビらせてくるので、強い心で Don’t Save を選択するといいでしょう。不要不急のコミット対象になるのを防ぐためです。

 

 

 

タイトル画面編

次はタイトル画面を用意します。

バックグラウンドと同じ要領でWidgeブループリントを作成します。

アセット名前は wb_Title としました。

f:id:hiyokosabrey:20210516145241p:plain

 

編集していきます。

キャンバスに、TextButton を配置します。

f:id:hiyokosabrey:20210516151300p:plain

階層が必要ないのでまずは適当に置いて大丈夫。

センタリング(中央揃え)したいので、Detailsから設定します。

まずは TextパーツからAnchors の中から 真ん中のアイコンを選びます。

f:id:hiyokosabrey:20210516154011p:plain

この時 Ctrl キーと Shiftキーを押しながらクリックすると数値入力の手間がいくらか省けます。

f:id:hiyokosabrey:20210516155316p:plain

Alignment X を 0.5 にすると、 Position X を 0 にするだけで水平方向は中央に配置できます。

あとは、 高さ(Position Y)と文字サイズ(Font > Size)、表示する文字列(Content > Text)をいい感じに設定します。

背景に合わせてカラーもお好みで。

 

テキストの次は Button も同じようにセンタリングします。

f:id:hiyokosabrey:20210516161217p:plain

中身が無いので、 ButtonText をドロップします。

f:id:hiyokosabrey:20210516161409p:plain

中におさまるとこのようになります。

 

ヒエラルキー上では親子関係になります。

f:id:hiyokosabrey:20210516161600p:plain

Button をフォーカスした状態で、Detailsタブの設定に Slot > Size to Content というのがあるので、ここを有効にすると、うまく収まってくれます。

f:id:hiyokosabrey:20210516161846p:plain

 

f:id:hiyokosabrey:20210516161945p:plain

Size To Content は「中身に合わせるよ」という意味になります。
この状態で、Text の設定を変更します。

f:id:hiyokosabrey:20210516162524p:plain

Padding 設定は 親子構造になると子の側で設定できるようになります。

設定方式が CSS に似ていますが、外側に対して働くイメージなのが、CSSと少しニュアンスの違うところです。

スタートボタンとしていい感じになれば、ひとまず完成とします。

このWidgetコンパイルして保存しておきます。

 

 

出題&回答ボタン画面編

また新たにWidgetを用意します。

アセット名前は wb_Main としました。

f:id:hiyokosabrey:20210516224252p:plain

また同じように必要なパーツを配置していきます。

まず Text を一つ配置。これは出題用のテキストが入ります。

f:id:hiyokosabrey:20210516230359p:plain

問題のテキストが複数行になるのを想定して、サイズを大きめに設定してあります。

文字サイズも読みやすく大きめに。

 

今回背景が明るめなのと、文字の色を黒くしたかったので少し大きめの Image を半透明にして下敷きを置くことにしました。

f:id:hiyokosabrey:20210516231348p:plain

名前を Image_Base に変更しています。

 

UMGでの表示優先(重なり)のコントロールは2種類。

ヒエラルキーでの上下位置 と ZOrder というパラメータです。今回はヒエラルキーで調整します。

f:id:hiyokosabrey:20210516232434p:plain

 

f:id:hiyokosabrey:20210516233619g:plain

後から足した ImageText の下に置かれるので ドラッグして上下を入れ替えるようにするだけでOK。

Photoshop のレイヤーと逆ですね。

 

 

次に Button を用意します。Button には Textも入れておきます。

f:id:hiyokosabrey:20210516233140p:plain

アンカーは左上のままにしておきます。

ここではサイズとPadding の設定にとどめます。

 

ここまではタイトル画面のWidgetと同じ構成になります。

 

さらにこのボタンをまっすぐ並べるための専用パネルを追加します。

Paletteタブの Panel カテゴリにある Vertical Box をドロップします。

f:id:hiyokosabrey:20210516234211p:plain

 

この Vertical Box の子になるように、 先に作った Button を入れます。キャンバスでは操作できないのでヒエラルキー上で親子にします。

f:id:hiyokosabrey:20210516235356g:plain

すると

せっかくサイズ調整したButton が大変なことに!

f:id:hiyokosabrey:20210516235518p:plain

大丈夫です。

まずはヒエラルキー上で Vertical Box を選択します。

f:id:hiyokosabrey:20210517000003p:plain

キャンバス上でマウスを使ってサイズを大きくするか、Details タブからサイズを変更できます。

f:id:hiyokosabrey:20210517000335g:plain

この Vertical Box に入れると、自動で、水平方向にストレッチする仕様になってます。

ちなみに Horizontal Box というのも用意されていて、こちらは垂直方向にストレッチします。

Vertical Box のサイズをざっくり決めたら、アンカーの設定と位置を調整します。

f:id:hiyokosabrey:20210517000638p:plain

高さは大体Button  4 つ分 を想定。

 

適当に拡げたら、中のButtonを選択状態にして

f:id:hiyokosabrey:20210517222841p:plain

Dupulicate(複製)します。右クリックメニューか Ctrl キー 押しながら wキー

f:id:hiyokosabrey:20210517222949p:plain

全部で4つ。

f:id:hiyokosabrey:20210517223655p:plain

 

Button 同士のスキマを開けるには、全部の Button を Shiftキーを押しながら選択状態にして、

f:id:hiyokosabrey:20210517223343p:plain

Detailsタブにある  Slot > Padding の設定で、 Bottom を調整します。

f:id:hiyokosabrey:20210517223849p:plain

 

f:id:hiyokosabrey:20210517224124p:plain

 

 レイアウト完成。

コンパイルして保存します。

 

 

正解演出画面編

つぎに正解した時の演出用画面を作ります。アセット名は wb_Right にしました。

f:id:hiyokosabrey:20210517231717p:plain

 

タイトル画面と全く同じ構成です。テキストが専用なのと、アニメーションがついているくらい。〇は全角文字(日本語の丸)

f:id:hiyokosabrey:20210517231948p:plain

アニメーションは いい感じに。

まずトラックを新しく追加します。

f:id:hiyokosabrey:20210517233529g:plain

IN と名前を付けました。

ヒエラルキーText → アニメーショントラックの IN の順にクリックして、ハイライトしたら、Detailsタブの下の方にある Render Transform > Scale でキーを打ちます。

キーを打つには、数値を調整して下の〇で囲んだボタンをクリックすると打てます。

f:id:hiyokosabrey:20210518000019p:plain

 

調整方法がたくさんあってここ紹介しきれないので、詳しい操作方法については公式のドキュメントをぜひぜひ

docs.unrealengine.com

こんな感じに打ちました。

f:id:hiyokosabrey:20210518000128p:plain

動きはこんな具合。

f:id:hiyokosabrey:20210518000150g:plain


アニメーションができたら、注意しておきたいことがあります。

f:id:hiyokosabrey:20210518003125p:plain

アニメーショントラックにハイライト(フォーカス状態)が残っていると、見た目の表示が、アニメーショントラックが優勢の状態なので、通常時の状態を見失ってしまうことがよくあります。アニメーションをつけるために変更した値が、そのままデフォルト状態になっていることがあって、いざ確認!というときになって あれ? というのがたびたび起こるのがUMGです。今のところ慣れるしかない感じですが、とにかくフォーカスを外して確認 するようにすれば意図しない動きを回避できます。

 

正解演出はこれでいったん完成です。

コンパイルして保存します。

 

 

 

誤答演出画面編

間違えたときの表示です。正解用を複製すると時短できます。

コンテンツブラウザに並んでいるアセットアイコン wb_Right の上で右クリックして、メニューからDuplicate を選択します。

f:id:hiyokosabrey:20210606164004p:plain

 

名前は wb_Wrong にしました。

f:id:hiyokosabrey:20210518010605p:plain

 

パーツの構成は正解演出と同じなので説明は省かせていただきます。

 

〇 を ×(全角の乗算記号)にしています。に変えて、サイズを調整していています。

f:id:hiyokosabrey:20210518224656p:plain



今度はアニメーションを残念な感じにします。

正解は Scaleアニメーション でしたが、Translation(位置) をアニメーションさせます。

f:id:hiyokosabrey:20210518011521g:plain

 

誤答演出もひとまず完成です。

コンパイルして保存します。

 

 

素材はできた。次はいよいよブループリント

ここまでお付き合いくださった方、おつかれさまでした。
《準備編》ということでまだ動きませんが、次回の記事でブループリントを駆使して完成させるとこまでやります。

 レイアウト操作に慣れていれば、30分かからないボリュームだと思います。

UE4のUMGを触り慣れていない方を想定して、比較的細かく操作方法について書いてみたので記事自体は結構なボリュームになってしまいました。次回はどうでしょう・・・

 

 

 つづきはこちら

 

limesode.hatenablog.com

 

 

 

 

 

 

 

雑記#20210417

今年も新人さんたちが入社してきました。去年のこの時期はいろいろとアレやコレやでもう大変でしたが、新型コロナに気を取られてもう一年が経ちました。早いものですね。まだまだ脅威は去っていないというかむしろ近づいてきてる気がするので、戦々恐々とする毎日です。UE4でもいじって心を落ち着かせるとしましょうか。小ネタですがブログに残しておきます。

 

 

 

最近Twitterにあげたやつ その1

あの最近話題の育成ゲームです。ついアニメも観てしまい、涙腺対応でティッシュの山を築きながら作りました。

最初『春のゲージ祭り』というお題で記事を書こうと思っていろいろ準備していたら、いつの間にか体力ゲージができていました。マテリアルを使ったゲージで、なるべくパーツ数を抑えていろいろ表現できないかと模索しているところだったので、さっそく参考にさせてもらうことにしました。

マテリアルでいろいろやりすぎるとGPUの負荷が心配にはなりますが、ゲージなので面積は大きくはないし、表示するパーツ数を増やさず情報量を増やすことができるので、結果的にオートレイアウト的な処理が減ります。もちろん実機で負荷検証するのは必須なんだけど、よいこは真似してみてね。

 

マテリアルはこんな感じ

f:id:hiyokosabrey:20210416005711p:plain

予想値 現在値 をそれぞれ Step で 0 と 1 に分けたものに、0.8 と 0.2 をかけてます。

f:id:hiyokosabrey:20210416013016p:plain

f:id:hiyokosabrey:20210416012444p:plain

足し算して 1.0 になればOK。

これを Lerp ノード に渡すと、濃淡が表現できます。

f:id:hiyokosabrey:20210416211158p:plain

1.0 のところは、グラデーションがそのままで、 0.0 のところは ベースのカラーが、 0.2 のところは線形補間(Linear Interporate)された状態になります。

f:id:hiyokosabrey:20210416013441p:plain

これで、特訓によって減少するであろう未来が表現できた。

 

次は増加するときの見た目。

加算と減算で条件分岐、とかやりたくなかったので、

f:id:hiyokosabrey:20210416212421p:plain

予想値 と 現在値 の差分を 計算に利用します。

f:id:hiyokosabrey:20210416213413p:plain

これをゲージ本体のカラー(グラデーション)の底上げに使います。

f:id:hiyokosabrey:20210416214133p:plain

加算するといい感じになるように底上げ具合を調節。

f:id:hiyokosabrey:20210416214412p:plain

 

予想値が下回った場合は減算になります。

f:id:hiyokosabrey:20210416214813p:plain

マイナス値をどうにかしないと、ということで登場するのが clampノード。

clampノードは 指定した範囲をオーバーした値はカットします。

正確には、 Min を超えれば Min の値、 Max を超えれば Max の値になります。ノードのデフォルトが Min = 0、 Max = 1.0 なので何もつないでませんが、ゼロ以下の値が入ってくると、しれっと 0.0 を返します。

f:id:hiyokosabrey:20210416215447p:plain

回復分のカラーに 常にこのclamp後の値を掛けてるので、加算のとき、減算のときで、2種類の状態を作り出せます。

 

掛け算と足し算だけでもこういった条件分岐みたいなことができるので、面白いですね。

掛け算のこの3つパターンを押さえておくとイイことあるかもよ。

0 × 0 = 0

0 × 1 = 0

1 × 1 = 1

掛け算に ゼロ が入ると問答無用で ゼロになります。

また、イチ を掛けると何も変化しません。

この辺をうまく組み合わせて作っていきます。もし触るのをためらっているUIデザイナーがいらっしゃるなら、UI表現の幅も広がるので、恐れずにぜひいろいろ試してほしいです。

 

せっかくなんで増減するアニメーションを作ってみました。

f:id:hiyokosabrey:20210416221115g:plain

 

ブループリントでは、ゲージのImageにセットしたマテリアルを、Dynamic Materia lInstance として変数化しておきます。これを使ってマテリアルにアクセスします。

f:id:hiyokosabrey:20210416221620p:plain

予想値をもらって反映するイベント(または関数)も用意。

 

マテリアルのパラメータをセットする関数はこんな感じ。

f:id:hiyokosabrey:20210416221803p:plain

今回 Float型の変数は3つ使ってます。

f:id:hiyokosabrey:20210416222257p:plain

 

増減のアニメーションは Set Timer by Eventノードで。

f:id:hiyokosabrey:20210416222031p:plain

 

やりたい仕様がうまくできるとパズルが完成したような心持ちがします。

と思いつつも、ゲームをプレイしながら増減するときの動きをよくよく観察していると、重ねて処理しているように見えるので、今回のつくりは完コピにはならなかったけど、いろいろ検証できたので面白かった。

 

 

 

 

 

最近Twitterにあげたやつ その2

 

ふと思いついて試してみたシリーズ。

この 〇れ味ゲージは過去記事でやってまして、当時はマテリアルを使いました。

limesode.hatenablog.com結構ややこしいことしてましたね。

 

 今回は HorizontalBox を使います。マテリアルは一切使用しません。とてもシンプルです。

f:id:hiyokosabrey:20210416224826p:plain


HorizontalBoxをひとつ、子供として色のついた Image を入れます。

f:id:hiyokosabrey:20210416225020p:plain

HorizontalBoxの子になると、親のタイプに合わせて Slot が変化します。

f:id:hiyokosabrey:20210416225850p:plain

Size の値を変更すると、幅が変わります。

すべての Sizeを 1.0 にすると、すべてが等幅な状態になります。

ぴっちりと隙間なく自動で調整してくれるので、個別にSizeをいじってやれば棒グラフ完成です。

可変しなくて固定の棒グラフならこれを量産して、表示を切り替えるだけで使えそうです。でもやっぱりスクリプトから制御したいですよね。というわけで・・・

 

まずは、Size を適用する関数。

f:id:hiyokosabrey:20210416231416p:plain

Get Child At ノードは、 HorozontalBox の 子要素を、Index番号でアクセスできるようにするノードです。

下の Make系 ノードは単体で検索するより、この場合、右上の Set Size ノードの左のピン In Size からドラッグするとすぐ近くに見つかります。

f:id:hiyokosabrey:20210416231928p:plain

 

Float型の配列を一つ作って、適当な値(テスト用)を入れます。

配列の数は HorizontalBox の Image と同じ数。

f:id:hiyokosabrey:20210416232657p:plain

 

これを計算して比率を求め、上の関数で適用します。

いったん全部足して最大値を求め、それで割ることで一つ一つの割合がわかります。

f:id:hiyokosabrey:20210416232834p:plain

LastIndexの値は一応 引数として受け取れるようにしてます。
テストだったら固定値を入れたつくりでも問題ないですが、こうしておくことで、一度できたこの関数を編集する機会が減らせます。結果調整の手数が減ります。

 

グラフの表示を更新するイベント(または関数)

f:id:hiyokosabrey:20210416235045p:plain

ゲージ全体の長さは 0~1.0 で受け取る仕様。500は実際に表示する最大の長さ。

ゲージの長さを実際の表示幅で受け取る仕様だと、デザインやレイアウトの変更でゲージそのものの長さを変更する際に大きな問題となります。パラメータを管理する者と、デザインを管理する者はおそらく別々だろうと思うので、なおさらこういった配慮はメンテナンスのコストを下げる効果があります。

 

f:id:hiyokosabrey:20210417000108p:plain

できあがり。

 

グラデーションのテクスチャ作って Image にセットすると見た目を少しアレンジできます。

f:id:hiyokosabrey:20210417114830p:plain

f:id:hiyokosabrey:20210417114725p:plain

 

 

 

 

文字でも世界観を

遊んでいて最近気づいた。

f:id:hiyokosabrey:20210417011037p:plain

 基本的に『馬』の表記を「ウマ」「バ」と回避しつつも、「有馬記念」だけはどうしようもなかったんだろうな。『有マ記念』・・・『アリマ記念』

 で、結果フォントのグリフいじってるようですね。たった一文字、この一文字を加工するだけで、このフィクションな世界のリアリティを感じさせてくれる心遣いがステキすぎる。

 外字として追加するのが簡単だしコストが一番安くできるんだけど、置換が必要になるうえ、テキスト管理のコストや置換漏れの確認工数なんかがパないので、おそらく馬(U+99AC)のグリフそのものをいじる方が安全ということだろうと思われる。自分だったら確実にそう提案する。TextMeshPro(埋め込まずにAtlasを使用する方)使ってるんだったらマージしてるかもしれない・・・?

 フォントベンダーの名前が見つけられなかったんだけど、オリジナルフォントじゃなければそれなりにコストと期間は支払っているはずで、それでもやってやろうという開発スタッフの愛と意気込みに感服です。さすがに馬偏の漢字はいじってないみたい。

 

 

ではでは

今回はこの辺で

誰かの何かに役に立てれば幸いです

 

 

9スライスを試してみたメモ

ダイアログウィンドウなんかのサイズが可変するウィンドウでよく見かけるUI表示で、制作環境によって呼び名が変わるようです。9スライスとか、9-patch とかいうやつ。

UE4でももちろん標準実装されているのでとても手軽に使えます。

詳しくはこちらの記事。

historia.co.jp

普通に使えるのに、わざわざマテリアルで試そうと思ったのは、カラーを乗せたかったから。

で、できたのがこれ。

 

 

f:id:hiyokosabrey:20210404135055p:plain

AlphaチャンネルとRGBカラーを分離すれば実現できるはず。ということでマテリアルと格闘することになったのでした。

 

UE4の Mergin指定はデザインに対して柔軟に合わせられるつくりなので、真似してみたかったけど、まずはシンプルなところから理解していこうということにしました。

今回は作り方というより考え方の記録みたいな内容です。

 

下図は、UMGでの指定方法。

f:id:hiyokosabrey:20210404152543p:plain

考えやすいように、Marginは 0.5 固定で進めます。

Marginはテクスチャの分割位置を上下左右の端から割合で指定するので、全部 0.5 ということは中央になります。

 

用意したテクスチャ ↓

f:id:hiyokosabrey:20210404144830p:plain

 

実際に描画する際は、この4分割のパーツを9か所に配置することになります。

f:id:hiyokosabrey:20210404152307p:plain

縦と横の中央部が延ばされます。

 

マテリアルでこのようなUVを作れればOKなわけです。

f:id:hiyokosabrey:20210404153913p:plain

 

まずは U方向(水平)について考えてみます。

 

変化量を縦軸にしてグラフにすると下図のようなイメージになります。

f:id:hiyokosabrey:20210404160306p:plain

何も手を加えなければ、0 ~ 1.0 へのまっすぐな直線です。これを指定したSize固定部分で分断して引き延ばす感じ。

 

ノードで組んでみるとこうなりました。

f:id:hiyokosabrey:20210404161037p:plain

Scalarパラメータノードが Size固定部分の値になります。

そこを if ノードで判定して、ナナメ(0→0.5 と 0.5→1.0 )にするか、0.5 にするかを仕分けています。

もっと頭のいい計算方法があると思う。

パッと見ややこしいし、U方向だけでこのボリューム感。ついでにSize固定幅の指定をピクセルで指定したいので、TexCoord[3] を活用。

これについてはこちらのツイートが参考になりました。

 

コピペとはいえ V方向のぶんも必要なので最終的にこうなりました。

f:id:hiyokosabrey:20210404162522p:plain

 

コンパクトにしたいので、HLSLのコードを書ける Customノードを試してみました。

f:id:hiyokosabrey:20210404164709p:plain


 1 |  float temp = 0.5 / Width;
 2 |  float result;
 3 |  if ( Value < Width ){
 4 |    result = temp * Value;
 5 |  }else {
 6 |    if ( (1 - Width) < Value ) {
 7 |      result = (Value -(1 - Width)) * temp + 0.5;
 8 |    }else {
 9 |      result = 0.5;
10|    }
11|  }
12|  return result;

 

すっきり。

f:id:hiyokosabrey:20210404174746p:plain

 

今回 ノードで組むより、コードで書いたほうが Instructions(命令)数は少なくなった。

f:id:hiyokosabrey:20210404175137p:plain

 

使ったテクスチャはこれ。

f:id:hiyokosabrey:20210404200330p:plain

 

できたマテリアルは、いつも通り Image に貼り付けて完成。

f:id:hiyokosabrey:20210404193556g:plain

 

これで途中で伸びることなくカラーテクスチャが自由にオーバーレイできるようになった。

f:id:hiyokosabrey:20210404195354p:plain

UVの計算方法については、結果オーライでまったく自信ないので、どなたか頭のいい人ご指摘いただけるとありがたいです。

 

テクスチャの品質で圧縮による劣化を少しでもマシにしたくて、RGB と Alphaを別々の解像度で作って合体させるというのを実践しているのですが、今回のネタもそこからのつながりです。

まだまだ、応用できそうですが今回はこのへんで

 

 

ではでは

すてきな9スライス ライフを!

 

 

 

レーダーチャート作ってみた

 

f:id:hiyokosabrey:20210327154555j:plain

いやぁレーダーチャートですよ。ゲームのUI作ってると、避けて通るのが難しいというか、ヘタに避けると事故るというか、かといって簡単には実装させてくれないというツンなところが憎いレーダーチャート。ステータス画面でキャラの成長度合いや武装なんかの性能差をパラメータ表示する際に使われることが多い印象。

ポリゴンメッシュのような柔軟な形状変化は、半透明テクスチャベースでの2D表現ではほぼ無理(直線の組み合わせなので頑張ればできますが、なり力技で無駄なパーツも増える)だし、プログラマさんへの負担がかなり高いのもレーダーチャートです。なのでプログラマさんの顔色伺いながらデザイン提案してきました。

かねてからレーダーチャートを自力で作ってみたくて、思いついたアイデアを実践してみたのが今回つぶやいたやつです。

たまたま思ってた感じに動作してくれたので、メモしておきます。

三角関数とかベクトルとかそういった計算は一切使ってません。

主に掛け算と引き算です。

さすがに こんな変則的な作り方が採用されることはないと思いますが、参考になれば幸いです。

 

 

blenderでメッシュを用意する

Verは 2.92 です。大したことしないので旧いVerでも他のDCCツールでも問題ないです。まず円錐を作ります。6角錐でも5角錐でもOK。底面は不要。

スケール をゼロにしてぺちゃんこにつぶしたら、スケールを「適用」して 1.0 に戻す。

[ObjectMode] モード Object → Apply → Scale

f:id:hiyokosabrey:20210327155834p:plain

この時 底面が残っていると、ポリゴンが重なってしまって作業しづらくなる。

(ぼくはこの後 X軸を 90度回して Apply します。)

 

[Vertex Paint] モードにして 頂点カラーをつける。

f:id:hiyokosabrey:20210327161029p:plain

このとき 中途半端な値にならないようにしっかり塗る

色の順番は法則とかないので適当でも大丈夫。

ただし中央は動かないので 黒(0,0,0)または白(1,1,1)推奨。

 

色がついたら、FBXで書き出し。

(今回 FBXのバージョンとかはデフォルト設定のまま)

正面方向と上方向の軸に注意。インポートしてみて向きがおかしかったらモデルを回転させるか、FBXの書き出しで対応するかどちらかで。この辺は、作業のやりやすさと、エンジンにインポート後の配置のしやすさを考慮すると自然と決まってくる。はず。

 

UE4でのインポート時のダイアログで、

Vertex Color Import Option を  Replace に変更する。

f:id:hiyokosabrey:20210328004351p:plain

マテリアルの設定は

探さない、作らない、読み込ませない の3無い運動で。

f:id:hiyokosabrey:20210327163013p:plain

 

無事インポートできら材料は揃ったので、次はマテリアルをどうにかすればほぼ完成。

 

新しくマテリアルを作成したら、

ShadingModel は Unlit(光源計算なし)を選択。

まず VertexColor をつなぎます。

f:id:hiyokosabrey:20210328005311p:plain

 

プレビュー用のメッシュを登録すると作業がはかどります。

f:id:hiyokosabrey:20210328005030p:plain

 

 

できあがった全体図

f:id:hiyokosabrey:20210327165548p:plain

 

まずは頂点カラーを取り出すところ

f:id:hiyokosabrey:20210327165717p:plain

各頂点のカラーから、ある数字を取り出すのにカスタムノードを使用。

中身こんな状態。

f:id:hiyokosabrey:20210327170021p:plain

Codeのところは

return float((Red * 4) + (Green * 2) + Blue);

Red, Green, Blue は下の Inputsのところで設定した名前。

 

何をやっているかというと、

RGB を 111 の 2進数と見立てて 0~7 の 10進数 に換算してる。

f:id:hiyokosabrey:20210327171446p:plain

 

これで、各頂点に番号を振ったのも同然。

あとは、個々でパラメータを反映してやるだけ。

 

blender のVertexPaint は デフォルトだとアルファが使えないので、今回のやり方だとRGBの3つしか使えないけど、アドオンでアルファを使えるようにしたら、ARGBの 4つが使えるので、最大15個の頂点を制御できると思う。試してないけど。

 

あとは、この 1 ~ 6 の値を if ノードで判定しながら頂点を動かします。

f:id:hiyokosabrey:20210327221544p:plain

LocalPositionノードは、メッシュが持つ頂点の位置で、メッシュの中央からの座標になります。

上の図の場合、VertexColor が RGB(0,1,1) のとき(= 3) という値が来たときだけ、 ScalarParameter(上図のRightUpper)を流して、それ以外は 0 を流します。

マテリアルが受け取る値は 0 ~ 1

f:id:hiyokosabrey:20210327223033p:plain

0 のときMAXなんで、 気持ち悪ければ OneMinus ノード使ってもいいのですが、計算が増えるので処理負荷を考えてここは受け入れています。

各頂点は、Meshの原点から離れた位置にいます。ここに掛け算することで、方向を保ったまま、原点に近づいたり離れたりするわけです。

で、この掛け算した結果を、元の頂点位置から引き算することで結果的に凹みます。

用意したMesh が最大値の状態なので、こういった発想に至りました。

 

あとは連鎖的に、次々各頂点の計算をして引いていきます。

f:id:hiyokosabrey:20210327224400p:plain

もう少し違うやり方もありそうな気がします。

  

中央以外の頂点を計算し終えたら仕上げ。

f:id:hiyokosabrey:20210327224649p:plain

TransformPosition に渡して、そこから AbsoluteWorldPosition を 引いてようやく 出力できます。すでに存在するメッシュに対して、部分的に頂点を動かしたら、この計算しておくことで、相対的な動きになります。

Lerp ノードのところは、頂点カラーを確認するためのものなので、以下の形で問題ないです。

f:id:hiyokosabrey:20210327230809p:plain

マテリアルは完成です。

 

新しく Actorブループリントを用意して、StaticMesh を  AddComponent します。

そこに インポートしたメッシュと出来立てのマテリアルをセット。

 

f:id:hiyokosabrey:20210327231943j:plain

 

メッシュのマテリアルをいじるには、Dynamic Material Instanceを用意します。

 

f:id:hiyokosabrey:20210327232814p:plain


Targetにつながった StaticMesh は、 Viewportで追加したやつ。左のリストからドラッグ&ドロップ。

Source Material のところに 今回用意したマテリアルをセット。あとはReturnValue ピンから 変数に昇格(Promote to Variable)させておきます。

 

パラメータを管理するための配列を用意します。

f:id:hiyokosabrey:20210327233722p:plain

 

配列の中身を個別に取り出す関数

f:id:hiyokosabrey:20210327233833p:plain

Pure型にするのをオススメ

 

そして、この配列の中身を一気にマテリアルに反映するのがカスタムイベント。

f:id:hiyokosabrey:20210327234239p:plain

下のほう見切れてるけど、同じような形なので省略。

マテリアルパラメータ名と、配列変数の Index が合ってさえいれば問題なし。

 

ひとまずこれで必要なものは全て揃いました。

 

あとは配列の中身を書き換えて、カスタムイベントを呼ぶ。

これだけです。

 

Twitterにあげた動画は、ランダムにパラメータ書き換えて遷移するように特別に組みました。

エンジンの操作(オペレーション)についてはかなり省いているので、わかりにくかったらごめんなさい。謎なところなどあればコメントいただけると補間します。

 

正7角形までだけど、 頂点の数が変わっても簡単に対応できます。

使用できるカラーは以下の8色。

f:id:hiyokosabrey:20210328001003p:plain

RGBの各輝度は 1.0 = 255 です。実は blender のRGBの扱い方が 0~1.0 なのです。

f:id:hiyokosabrey:20210328001334p:plain

将来的に、HDR時代が当たり前になったら、255 とか FF みたいなこと言うと年寄り扱いされるかもしれないので今から慣れておくといいかも。

 

円錐の角数を変えてたので試してみた。マテリアルは使いまわし。

f:id:hiyokosabrey:20210328011746j:plain

ブループリント複製して、StaticMeshの中身差し替えて、減った頂点のぶん不要な処理を削っただけです。

 

ひとまずここまで作れて満足してます。

UE4は普通にメッシュ描けるので、ぶっちゃけこの方法は必要ないと思います。

頂点カラーで特定の頂点を動かすことができるのに気づけたのはよかった。

 

Widgetでシェイプが扱えるようになるといいな。

 

ではでは

すてきなレーダーチャートライフを!

 

UMGのスライダーをシークバー風に変える

先日のツイートを一応メモっておきます。

スライダー道は奥が深いですね。

 

きっかけは @HirofumiSeo さんのこのツイート

 

気になったのでいろいろ試してみるもドラッグ&ドロップでつまづいたので、取り急ぎ現行のスライダーを改造することにした次第。

f:id:hiyokosabrey:20210221103337p:plain

 

ちなみに ちゃんとドラッグできるやつはこちらの @seiko_dev さんのツイート。

 素晴らしいです。

 

今までゲームパッドありきで考える習慣のおかげで、ドラッグ周りの仕様を触ってこなかったのが悔やまれます。

でぼくが作ったのはこれ。

 

 

とりあえず作り方メモ

 

以前にも似たようなのを作ってましたが、ゲームコンフィグのような汎用性はいったん置きにして、1画面に1本想定、後からレイアウト調整がしやすいのを目指しました。

 

マテリアルパラメータコレクションを使います。

f:id:hiyokosabrey:20210221005001p:plain

f:id:hiyokosabrey:20210221005823p:plain

Scalarパラメータを追加。

 

このパラメータを使ってマテリアルを用意します。

f:id:hiyokosabrey:20210221011129p:plain

CollectionParameterノードに、用意しておいたパラメータコレクションをセットします。黄色いのがゲージカラー、グレーが下地のカラーです。

 

1パラメータ1マテリアルになるので、画面に同時に表示するスライダの数ぶんマテリアルアセットを用意する必要が出てきます。同時に表示しないのであれば使いまわせます。

 

次にWidgetブループリント

まずキャンバスを用意

スライダーたちを格納する HorizontalBoxから

f:id:hiyokosabrey:20210221105017p:plain

HorizontalBox に入れるUMGのパーツは3つ。

順番として ButtonSizeBoxButton になるように入れます。

それぞれに子供として、

TextBlockSlider を入れてます。

f:id:hiyokosabrey:20210221012919p:plain

プロパティを触るのは最小限にしたいので、なるべくデフォルト設定でレイアウトします。

 

HorizontalBox は中身に合わせて自動的にサイズを合わせる Size to Contents を有効にしておきます。

f:id:hiyokosabrey:20210221015200p:plain

 

  

 

スライダーの長さを調整する際の肝になるのが SizeBox

f:id:hiyokosabrey:20210221013650p:plain

Width Override で決定します。

 

UMGでは、HorizontalBox の子として、直接 Slider を入れると Slider の持つ Canvas Panel Slot が置き換わってしまう仕様になってます。おかげでサイズがちゃんと認識されなくなってしまうのを解決するためにSizeBoxでくるむことにしました。

 

↓左が通常時、右がHorizontalBoxの子にしたときの状態。

f:id:hiyokosabrey:20210221110440p:plain

このへんオートレイアウト系のしくみなので、おそらく何か理由はあると思いますが、スライダーのサイズ情報が別の Slot にあればよさそうではあります。

f:id:hiyokosabrey:20210221110515p:plain

 

 

スライダーの長さは SizeBox に任せるとして、見た目を整えていきます。

 

スライダーのパーツはシンプルな構成で2つ。

f:id:hiyokosabrey:20210221112606p:plain

 

Detail(詳細) パネルの Style の項目に Normal Bar ImageHovered Bar Image があります。

f:id:hiyokosabrey:20210221015456p:plain

Image のところに、用意しておいたマテリアルをセットします。

Normal は通常時、Hovered は マウスカーソルが上に乗った時を意味します。Normalの方の Tintカラーを少し暗くすると、操作したときに効果がわかります。

Disabled はスライダーが無効な時の状態ですが、条件的にあり得る場合はここにも同じようにマテリアルをセットしておきます。

Bar(溝) の下に 続けて、Thumb(つまみ)の設定と、Barの太さの設定。

f:id:hiyokosabrey:20210221112722p:plain

つまみのビジュアルはここで消します。

Draw As を None にすることで描画はされなくなりますが、Image Sizeは生きていて、Barの見た目の長さに影響するので、ゼロ にします。

f:id:hiyokosabrey:20210221113418p:plain

スライダーの長さにこだわるのは、スライダーで扱う最大値とピクセル表示量の差をできるだけ整数倍にしやすくするのが目的です。計算の仕組み上仕方がないと分かっていても、見た目に「わかる」「わからない」は重要です。にんげんだもの

というわけで、エンジンのお気遣いは排除します。これで単純に SizeBox の値だけでコントロールできるようになりました。

 

スライダーの設定はこれで終了。

次は 再ヘッダ的なカレント位置を示す TextBlock

 

f:id:hiyokosabrey:20210221104637p:plain
中央揃えf:id:hiyokosabrey:20210221012359p:plain にします。

数字と|は間に改行を入れて2行にしています。

行間は Line Height Percentage で調整できます。

f:id:hiyokosabrey:20210221121600p:plain

ブループリントから書き換えるので、 Is Variable を有効にするのも忘れずに。

f:id:hiyokosabrey:20210221121812p:plain

このTextBlockは ゲージの左端に合わせて座標を決めます。実際に動かす際は、RenderTransloation を使って相対的に動かすので、この初期位置だけを合わしておけばOK。

 

これでキャンバスの準備はできました。

次にWidgetブループリント

Float型の変数を作って、Event Pre Construct につないでセットします。

セットする値は、 SizeBox から取得します。

f:id:hiyokosabrey:20210221122729p:plain

もう一つ スライダーの最大量を保持する Float型の変数を追加。

f:id:hiyokosabrey:20210221125908p:plain

ついでにスライダーのプロパティもここで変更します。

 

スライダーの変更を見た目に反映する関数を作ります。

Bar部分にセットしたマテリアルを更新。

f:id:hiyokosabrey:20210221130809p:plain

テキストの内容とポジションを更新。

f:id:hiyokosabrey:20210221130818p:plain


ほぼこれで完成です。

試しに Event Construction に関数をつないで確認してみます。

f:id:hiyokosabrey:20210221135828p:plain

 

レベルブループリントからViewportに追加して再生します。

f:id:hiyokosabrey:20210221132854g:plain



あとはボタンを押したときの処理。

UI的には Numeric Stepper に相当します。

編集画面を Designer に切り替えて、Button のDetailタブ(詳細)からイベントを作成します。On Clicked のプラスボタンをクリック。

f:id:hiyokosabrey:20210221134525p:plain

イベントグラフにイベントノードが現れます。

f:id:hiyokosabrey:20210221135111p:plain

ここにクリックした際のふるまい(挙動)を用意します。

f:id:hiyokosabrey:20210221135359p:plain

 

再生して確認します。

ついでにボタンのテキストも変えてみました。

f:id:hiyokosabrey:20210221140051g:plain

 

改造は以上です。

 

実は UIデザイナー向けのポートフォリオUE4で作ろうというプロジェクトを目論んでいるので、ちょうどよいものができました。

スライドの切り替え等に使えそうです。

 

 

ここからはスライダーに関しての考察とかなんとか

スライダーといえば、ゲームコンテンツの話に限ると、遊びやすさをカスタマイズするためのセッティング画面で見かけるものがほとんどで、その用途はたいてい音量を調整するためのもの。他の要素もスライダーの形式をとりつつも、ステップ(刻み)がサウンドほど細かくないので、スライダーである必要がなかったりします。

 

用途と操作するデバイスによって有利不利があるので、全て書ききるのは文字量がえらいことになりそう、というか今はちゃんと整理できてないので、またどこかでまとめてみたいと思います。

 

UE4 の UMGに用意されているスライダーは、音声ボリュームの調整を主用途として想定されている印象。

クリックした際に、ポイントした位置につまみが移動するのは、今の位置から微調整したいわけではないのでは?と推測します。音量って、ステップ(変化の刻み)が細かくてちょっと動かしたぐらいでは、差異がわかりにくいのもあるのかなと思います。

よく見かける3つのボリューム SE、BGM、VOICE  のバランスをミキサーのように扱うからこそのスライダーだと考えると、精度というよりは比較を優先しているのかなと。

 

また、スライダーUIにとって、つまみの大きさと見た目は大変重要です。

マウスのような手首や腕で操作するデバイスでUIを細かく操作するのは、なかなか鍛錬が必要ですし、ゲームパッドに至ってはスライダーはフリーカーソルと並んで操作が面倒なUIの上位にくるやつです。それぞれでつまみに対する最適なサイズがあります。

 

今回の事案で、いくつか設定されている機能要件の中に、

つまみをマウスボタンで押下しただけでは動かない

つまみ以外でクリックしたらその場所につまみがジャンプする

の2つがあります。

 

仮に一つ目の要件を満たしていたとしても、

つまみのサイズ小さくしすぎるとカーソルを合わせにくくなり、ジャンプしやすくなるので要件を満たすのは難しくなります。

大きすぎると、そのぶん離れた位置にしかジャンプできなくなります。

なかなか興味深い悩みです。

 

つまみの大きさについては、マウスを操作する方のシチュエーションとスキルによって決めていくことになると思います。

センサーの分解能や、カーソルスピードも関係します。ボタンを押下したときにマウスが動いてしまうとかも対策が必要かもしれません。

 モニタの大きさと解像度の関係も大事です。

 

こういった用途や使う人に合わせて細かいチューニングが必要なのが、UI開発の面倒くさいとこでもあり、また面白いとこです。

常に最適解を求めていくのが大事という志向なので、基本、「使いまわし」 は考えないようにしています。使いまわすのはパーツやアセットではなく経験則。

実際に試してみると、気づかなかったいろんな事象がチラチラするので、試行錯誤はやってやりすぎるということはないなと思っています。

 

にしてもUE4のドラッグ周りの仕様が少し見えてきたので、もっと検証してみたい。マルチプラットフォーム開発は、特定のデバイスに例外的に対応するのは避ける傾向があります。最大公約数というかベン図の重なったところで答えを見つけようとするので、どうしてもそのデバイスの性能をどこかで切り捨てているのも事実。パズルのようで難しいですがうまく解決できるように、いろんなアプローチを試していきたいですね。

 

なんか長くなりましたが今回はこの辺で

 ではでは

ステキなスライダーライフを!

 

 

 

 

 

雑記#20210219

最近Twitterにあげたやつ

f:id:hiyokosabrey:20210215231418g:plain

 

とくに何かに使えそうというほどのものではないけど、つい出来心で「テクスチャ1枚できそう」って思ってしまったやつ。

f:id:hiyokosabrey:20210215235610p:plain

 ゲームって、基本リアルタイムレンダリングです。AfterEffectsのように、どんなに重い描画処理だろうと1フレームずつキッチリ計算してエンコード、後から滑らか再生といういうわけにはいかないので、効率のいいデータ管理や描画処理が求められます。その中でも UIに関しては、メモリに常駐させる要素も多く、扱えるデータや処理は他のキャラや背景、エフェクトに比べると圧倒的にシビアです。

 テクスチャを複数枚持つのと、1枚にまとめるのとでは、占有するメモリサイズが同じでも効率が変わってきます。テクスチャキャッシュの使い方とファイルアクセスの回数をできるだけ少なくする工夫がポイントだったりします。テクスチャが大きすぎても逆にキャッシュに乗らなくて効率が下がることがあります。 この辺は新しいハードが出るたびにちょっとずつ技術革新がなされているので、徐々に頭を悩ませる機会は減ってる気はしますが、ゲームの構造が複雑になってるぶん別の悩みに置き換わっている気がしないでもないです。

 

長々と書いてしまいましたけど、参考程度に作り方のご紹介。

まずは回したい素材をモノクロのフラットな絵で用意します。

テクスチャサイズは 128x128

f:id:hiyokosabrey:20210216001531p:plainf:id:hiyokosabrey:20210216001759p:plain

以前にもブログに登場した MendakoChanです。

これをPhotoshopでアルファチャンネルにします。

次はRGB(色)チャンネルのレイヤーを作ります。

f:id:hiyokosabrey:20210216002011p:plain

レイヤーのブレンドは、 覆い焼き(リニア)-加算 にします。

この状態でテクスチャに描き出してみます。

 

UE4にインポートしたら、マテリアルはこのようにつなぎます。

f:id:hiyokosabrey:20210216003507p:plain

これで、リング3つ分作ったら Widgetで重ねて表示してみます。

f:id:hiyokosabrey:20210216003644p:plain

隙間が空いてしまいました。

そこで、テクスチャにリングに一工夫。

 

ほんの少し小さい黒丸を間に 通常ブレンドで挟みます。

f:id:hiyokosabrey:20210216004149p:plain

 

f:id:hiyokosabrey:20210216004925p:plain

黒丸を入れることで、テクスチャにリングができたので、マテリアルは Subtract が減った分シンプルになります。

f:id:hiyokosabrey:20210216005237p:plain

f:id:hiyokosabrey:20210216005248p:plain

f:id:hiyokosabrey:20210216005258p:plain

確認してみます。

f:id:hiyokosabrey:20210216005557p:plain

隙間が消えました。いい感じです。

あとは、時間差をつけてアニメーションさせるだけ。

f:id:hiyokosabrey:20210216005857p:plain

 

f:id:hiyokosabrey:20210216010737g:plain

キャプチャが若干同期してなくてぎこちないですがなんとか完成です。

 ちょっとやってみたかっただけのネタです。

何かのヒラメキになればいいのですけど・・・

 

 

マダミス遊んだ

先日、マーダーミステリーというジャンルの『狂気山脈 陰謀の分水嶺』 というゲームを遊びました。この記事では内容には触れないのでご安心を。マダミスはここ数年での人気がうなぎ上り?のようで、気にはなりつつも、ある程度人数が揃わないとプレイできないというのと、昨今の感染症対策により指を咥えて眺めるしかなかったのでした。

ふと雑談のはずみで、急遽やろうということになったので、バタバタと準備を進めることに。

いろいろ訳あって、ボイスチャットの環境を用意してなかったので、やんわり断ろうと思ったけど、このまま時代の にノリ遅れるのはカッチョ悪いよなと思い、家族の前ではいつかリモートワークをする日がくるかもしれないなどとつぶやきながらなんとか書斎を確保。

Discord の扱いも含め完全なる初心者だったので、最初は緊張したけどそのうち慣れた。音声の調整に手間取ったので、なんかうまいことフィードバックできる仕組みがあればいいなと思う。

 

で、ボイスチャットは Discord 、 ゲームはオンラインセッションツールとして ココフォリア を選択。

プレイは共有のボードに並んだカードをめくりつつ、会話しつつで進めていく。カードは最初「非公開」の状態で伏せられてて、めくる際には「全員に公開」と「自分だけが見る」という状態を選べる。これだけの操作で、十分ゲームになりうるのがすごい。全体公開はそのまま隠し事はしません、というポーズになるし、特定の誰かを揺さぶる効果もある。自分だけが見る場合、カードの情報をそのまま伝えてもいいし、嘘を混ぜてもいい。見せないことで疑惑の種を蒔くこともできる。

そもそものゲームのメカニクスがうまくできてるのもあるけど、アプリ的にインターフェイスを見てみるととてもシンプル。カードのグラフィックの上で右クリックして選択するだけの機能があれば遊べてしまう。あとはカードやチップ、トークンなどのグラフィックを配置して、マウスでドラッグできれば十分だ。テキストチャットとダイスロールの機能も用意されてるので、結構な数のアナログゲームが遊べそう。ネックになるとしたらハンドアウトなど諸々のグラフィックを用意する手間かな。裏と表の扱いも準備するとなれば大変そう。

とはいえ物理カードがなくても遊べるのが素晴らしいので、オリジナルのアナログゲームを作ってみたいなと思ったら、印刷しなくても、この環境で遠くの仲間とテストプレイしたり調整できるのはすごくいい環境。

 

とまぁ、

そんなこんなで、とても楽しく遊べました。シナリオも面白かった。

額を寄せ合って遊ぶアナログゲームにとっては厳しいご時世ですが、こういったセッションツールやチャットの環境がどんどん登場して進化してるのは興味深いですね。

アナログゲームデジタルゲームの境界が一部で溶けていく感じがして、ちょっとワクワクしてます。

 

 

ではでは

今回はこの辺で