みつまめ杏仁

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

アセットを作らずにWidgetを作る

Widgetで何か表示しようとすると、UMGでキャンバスにパーツを置いていきます。これはあらかじめ表示する数が分かっている場合ですが、数を必要に応じて動的に配置したいときは、別のWidgetブループリントをアセットとして用意しておいて、これをCreateWidgetノードを使って並べます。

f:id:hiyokosabrey:20160925155636p:plain

テキストを表示する際に色をつけたり、ボールドにしたりしたくなった場合にいちいちアセットから用意するのもなんだかな~・・・ と常々思っていました。

 

ありました。

ブループリントだけで自由に作る方法が。

Create Widget ノードを取り出してよく見ると、Construct NONE と書かれています。

そうか!?

 

ということで、さっそく実践。

まず変数を用意します。といっても正しくはクラスです。

Variablesのところの追加ボタンをクリックして、"text" で検索すると出てきます。

f:id:hiyokosabrey:20160925160302p:plain

上の図のように白い▲のところから Class を選択します。

Detailsタブから名前と初期値をセットするのですが、下のようになっているので焦らずにコンパイルします。

f:id:hiyokosabrey:20160925160728p:plain

適当に名前を付けて、一番下のプルダウンを TextBlock に変更します。

f:id:hiyokosabrey:20160925161009p:plain

これをグラフにドラッグ&ドロップします。

f:id:hiyokosabrey:20160925161340p:plain

ドロップしたクラスのピンからドラッグしてConstruct Object from Class ノードを取り出します。

f:id:hiyokosabrey:20160925161714p:plain

クラスからオブジェクトを作るぜ! というノードです。

f:id:hiyokosabrey:20160925161847p:plain

ノードのキャプションが Construct Text になっています。似てますね。

Outerピンに何もつながないでいると、コンパイルエラーになるので、Selfノードをつないでおきます。

f:id:hiyokosabrey:20160925162442p:plain

最後にReturnValueを適当なキャンバスパネルに Add Child to Canvas してやります。

f:id:hiyokosabrey:20160925162821p:plain

これが基本のフローです。

色とかフォントを変えるのはこんな感じ。

f:id:hiyokosabrey:20160925165225p:plain

端っこのAutoSizeは、有効にしておかないと、文字が欠けてしまってすべて表示されません。

 

この方法を使えば好きなだけ画面にテキストを表示できます。

ショットガンのヒットダメージ表示とかにも使えそうです。

 

Imageも同じ方法で大量生産できます。

 

ではでは

次回もうちょっと遊んでみます。

 

 

 

 

マテリアル操作で簡単アイコン切り替え

UMGのマテリアル操作でアイコンイメージを切り替える記事を前に書きました。

ちょっとだけラクする方法をひらめいたのでメモしておきます。

簡単といっても指定が楽になる程度ですが。

 

limesode.hatenablog.com

このときは、アイコンのUV値(テクスチャ内の場所)をそのまま配列にしていました。

f:id:hiyokosabrey:20160112205453p:plain

 小数点の扱いがちょっと・・・な感じです。

 

まず今回用に新しくテクスチャを用意しました。

512x256 の長方形です。

相変わらず、Webdingsという書体で構成しています。

 

↓RGBはこんな感じ。

f:id:hiyokosabrey:20160918001216p:plain

↓アルファチャンネルはこんな感じ。

f:id:hiyokosabrey:20160918001313p:plain

 

アイコン1個分の大きさは 80x80 です。今回長方形のテクスチャなのでTilingの値がUとVで異なります。

UV値を扱う場合、 値の範囲は 0.0 ~ 1.0 なので、

値を求めるときは  ( 移動量もしくはサイズ ÷ テクスチャサイズ )で計算します。

Uの値は 80 / 512 で 0.15625

Vの値は 80 / 256 で 0.3125

になります。

f:id:hiyokosabrey:20160918001757p:plain

半角のスラッシュは、プログラミングの世界では 『割り算』を意味します。

分数表記で 1/2 と書いたりしますが、そういうことです。

割り算のノードを取り出すときに使います。ちなみに掛け算は アスタリスクです。

 

3Dモデルを作る方々はこんなUVの計算なんか無縁なんですが、UIデザイナーは日々こんな小数点と闘っているのです。えへん。

 

で、この値をマテリアルに仕込んでいきます。

今回見た目に発光させたいので、Blend Mode を Additive にしました。

f:id:hiyokosabrey:20160918003249p:plain

まずは色を付けるところから。色を変えるためにベクター型のパラメータを2つ。

f:id:hiyokosabrey:20160918004439p:plain

 

つぎにUVを操作するとこ。

f:id:hiyokosabrey:20160918010345p:plain

ベクター型の中身である4つのFloat型、RGBA のうち、RとGをTilingの値としています。BとAをOffestにしていますがTilingと掛けているところが今回のポイントです。

マテリアルは以上で完成です。

 

前回の記事と同様にしてキャンバスに並べてブループリントから変更してやるだけなのですが、配列の値を変えます。その前にアイコンの並びを確認。キレイに並んでいれば配列を使う必要はないのですが、削除したり追加したりしているうちに制作終盤で下図のように不規則になることもあります。

f:id:hiyokosabrey:20160918100237p:plain

普通テクスチャ内でアイコンの場所が変わっても、アイコンを管理する番号(ID的な)は仕様的に変更することはしません。バグの元になります。なので、アイコンが順番通りに並んでいなくても、管理番号さえ変えなければ問題ないので配列が便利なのです。

 

今回、マテリアルに仕込んだ計算でこの場所の指定がラクになります。

左上のアイコンを(0,0)として右下のアイコンが(5,2) という形になります。

f:id:hiyokosabrey:20160918101013p:plain

 

配列にするとこんな感じ。メンテナンスするならどちらが簡単か一目瞭然です。

f:id:hiyokosabrey:20160918102218p:plain

アンリアルエンジンでは数値のフォームで四則演算が使えます。

左側の場合 一旦 0.15625 というベースの数字を [Ctrl] +[ C]キー でクリップボードに入れたら、あとは[Ctrl] +[ V]キーでペーストして、 *2 とか *5 を後ろに入力して[Enter]キーを押すと計算結果に変わります。

f:id:hiyokosabrey:20160918103127p:plain

テクスチャが長方形の場合、UとVでベースの数字が違うのと、アイコンのサイズとテクスチャのサイズを忘れた頃に編集することになると思うので、それなりに面倒です。

テクスチャをパッと見て、左から何個目、上から何個目って数えた方が早いです。

 

で、表示テスト。

f:id:hiyokosabrey:20160918104805p:plain

 

 ちょっと遊んでみました。

f:id:hiyokosabrey:20160918112925g:plain

カーソルキーでフォーカスを切り替えています。上下左右はループするすようにしています。

今回のマテリアル操作自体は、新しいテクニックではないです多分。単に自分で勝手に「そうかその手があったか」って盛り上がったので、記事にしてみました。

 

基本的な操作を習得するので問題ないですが、制作の工程を長い目で見ると、まだまだ効率化の余地はあるなぁ、と長年やってきて思うわけです。

 

ではでは、ステキなUVライフを!

 

 

UMGでリストボックスを作ってみる 《おまけ》

前回作ったリストボックスにもう少しだけおまけを追加してみようかと。

 

limesode.hatenablog.com

limesode.hatenablog.com

 リストボックスは、全体の一部分しか見えていないので、「もうこれ以上ないよ」または「まだ続くよ」というのをユーザーに伝えてあげた方が良いと思います。

伝え方としてはいくつかの方法があります。

 

・スクロールバー

・分数表記

・矢印でスクロール可能である表示

・ちら見せ

 

スクロールバーは全体の総数が分かってさらに今この辺、という示し方ができるので最強の部類です。総数が分かって今どこ、というのが分かるという意味では分数表記もアリですが、リストタイプよりページ切り替えするタイプに向いています。簡単な表示でそんなにややこしくないのが、矢印で示すタイプ。総数が分からないのが難点ですが、小規模のリストであればデザインも軽くできてそんなに悪くないと思います。

あとはパーツを必要としない、ちら見せ。まだ先があるように一部分だけを見せます。簡単そうだけどちょっとだけ補正の計算がややこしいです。

 

というわけで、今回スクロールボックスを使わなかったので、意地でもスクロールバーに頼らない表示を実装してみます。

 

で矢印タイプを作ってみます。

まずは、矢印のテクスチャ。64x32。

f:id:hiyokosabrey:20160915012120p:plain

テクスチャ容量節約のためMaskテクスチャにします。

アルファチャンネル無しの24bitのTarga形式です。

インポート設定は以下。

f:id:hiyokosabrey:20160915012653p:plain

設定して保存したら、コンテンツブラウザのアイコン上で右クリックしてマテリアルを作成します。

f:id:hiyokosabrey:20160915012836p:plain

UMGで使用するので、Material Domain(マテリアル属性)を Surface から Use rInterface に変更します。

f:id:hiyokosabrey:20160915013346p:plain

↓↓↓ Blend Mode はOpacityを使いたいので、Translucent にします。

f:id:hiyokosabrey:20160915013359p:plain

ノードはこのようにつなぎます。

f:id:hiyokosabrey:20160915013829p:plain

マテリアルはこれで完成です。点滅させたりカラーを重ねたりしても面白いかもです。

 

前回作った『親』Widgetを編集します。

UMGで Image を2つキャンバスにレイアウトします。

f:id:hiyokosabrey:20160915014212p:plain

Detailsタブの Appearance > Brush > Image のところに作ったマテリアルをセットします。矢印は上向きしか用意していないので、下側の矢印は回転させます。

Detailsタブの、Render Transform > Transform > Angle の値を -180 にしてます。

最初は消えていてほしいので、

Detailsタブの、Behavior >VisibilityHidden にしておきます。

Widgetブループリントから触るので、IsVariableのチェックも確認。

 

編集モードをGraphに切り替えます。Event Tickにつないでいるところで空いているピンがあります。

f:id:hiyokosabrey:20160915015751p:plain

ここに矢印を出したり消したりする処理をつなぎます。

 

 表示範囲が一番上、もしくは一番下になって初めて消えて、それ以外では表示します。

f:id:hiyokosabrey:20160916001737p:plain

 配列のInde番号は 0 からスタートするので、個数を見ると、最後のIndex番号より1つ多い数字になります。(慣れないとよく混乱します)

ViewRange_Bottomも見た目の数(=ViewRange_Num)を素直に足しているので、値としては1多い状態です。こういった値を扱うとき困るのが判定部分だと思います。

f:id:hiyokosabrey:20160916052030p:plain

つなぎ方次第で同じ結果になるものもあってややこしいのですが、AとBどちらのピンを基準に考えるかがポイントです。

なので、こうなります。

f:id:hiyokosabrey:20160916045905p:plain

 今回は ==(イコール)を選びましたが、他のものでも問題なく動作させることができます。たとえば↓

f:id:hiyokosabrey:20160916053005p:plain

ViewRange_Top の値が、0 だったら Hidden(非表示)  と、

ViewRange_Top の値が、0より大きかったら Visible(表示) は同じ結果になります。

 

というわけで再生してみると

f:id:hiyokosabrey:20160916054854g:plain

 

いい感じになりました。

今回 あまり端折らないようにしようと心がけてみたのですがいかがだったでしょうか?

解らない部分などありましたらコメントいただければ、頑張ってお答えします。

ではでは

 

UMGでリストボックスを作ってみる 《続き》

 前回でリストを表示するとこまでできました。

limesode.hatenablog.com

 今回はカーソルの移動と、表示範囲の移動を作っていきます。

 

カーソルの移動とキー入力

カーソルを動かすためには、「いまここ」というのが分かっていれば

次に移動する場所が計算できます。そのための変数をInteger型で作って Event Construct ノードのすぐあとにつなぎます。FocusIndex と命名。

f:id:hiyokosabrey:20160912222408p:plain

つながなくても初期値はセットできますが、「Set」の状態で初めの方につないでおくことで、初期値が分かりやすくなるのでオススメです。

 

カーソルの移動範囲はリストアイテムの先頭から最後までです。

先頭は0で問題ないとして、最後はどうやって調べる?

数があらかじめ決まっているわけではないし。

配列に好きなだけテキストを入れる仕様なので、その自由度を尊重して、Length ノードを使います。そしてその値を保持しておく変数を用意します。

f:id:hiyokosabrey:20160912223510p:plain

 

カーソル用の変数が用意できたところで、キー入力を受け取れるようにします。

ポイントは get Player Controller ノードです。そして Was Input Key Just Pressed ノードです。

f:id:hiyokosabrey:20160912224154p:plain

Keyのところに操作したいデバイスのボタン等をセットします。上の図はキーボードのカーソルキー「↑」と「↓」です。ゲームパッドだと、D-Pad の UpとDown になります。ちなみに D-Pad の D は Directional のDなので、方向キーのことです。

ReturnValueピンが赤いので、ブーリアンで値が出てきます。True か False です。ということで Branchノードをつなぎます。さらに Event Tick ノードともつなぎます。

f:id:hiyokosabrey:20160912225102p:plain

 

キーボードとゲームパッド両方で操作したい場合は、こちらの記事を参考にしてみてください。

limesode.hatenablog.com

 それぞれのBranchノードから、変数 FocusIndex の値を プラスマイナスするようにつなぎます。

f:id:hiyokosabrey:20160912231612p:plain

VerticalBox にアイテムを追加すると、上から下に向かって足されていきます。なので上方向にカーソルを進めるには、FocusIndexの値を減らせばいいわけです。

f:id:hiyokosabrey:20160912232327p:plain

一旦増やしたり減らしてみて、範囲を越えてないかチェックします。無事範囲に収まっていれば次に進みますが、越えていれば何もしません。

越えていなければ、+1、-1した値を、FocusIndexに入れます。これで変数がカウントアップまたはダウンしたことになります。

f:id:hiyokosabrey:20160913003038p:plain

この新しくなった値で、配列に入れてある『子』Widgetのリストアイテムの関数を呼び出します。フォーカス状態にする関数です。

CreateWidgetした際に配列に積んでいった『子』WidgetをGetで指定してフォーカス状態にします。

 

この辺でテストしてみましょう。

f:id:hiyokosabrey:20160913003540p:plain

動くには動きましたが動かすたびにフォーカス状態になっていきます。

デフォルトに戻す処理を入れていないのです。

で、入れる場所は2か所。まだFocusIndexの値が更新される直前です。

f:id:hiyokosabrey:20160913003959p:plain

ゴチャついてきたので、マクロを作って差し込むことにします。setFocus関数につないだのと同じような形です。

f:id:hiyokosabrey:20160913004256p:plain

setListItemDefault という名前にしました。

f:id:hiyokosabrey:20160913004806p:plain

これでテストしてみましょう。

f:id:hiyokosabrey:20160913005000p:plain

いい感じです。

ですが、下に動かすと表示範囲の外に行ってしまいます。

 

 

表示範囲の移動

 表示範囲を越えたのかどうかを調べて、越えていれば表示範囲を動かせばいいのですが、表示範囲を管理する変数が必要です。Integer型を3つ用意します。

f:id:hiyokosabrey:20160913210845p:plain

 これを最初の方に仕込みます。仕込む場所は ↓

f:id:hiyokosabrey:20160913211211p:plain

カーソル位置をセットしている直後に仕込みます。見えている範囲はカーソルが一番上にある状態でスタートしたいからです。

f:id:hiyokosabrey:20160913211415p:plain

カーソルの位置を基準に変数の初期値を決めてセットしています。

見えている数 ViewRange_Num は見た目に見えている数を初期値として持たせています。今回は 8個見えているので、

f:id:hiyokosabrey:20160913211947p:plainとしています。

カーソルの初期位置と違って、最初から最後まで変動しないのと、デザイナの都合なのとで、特に明示しなくても誰も困らないので明示しなくていいかなと。

こういうのを「定数」とか言います。

ちなみにカーソルの初期位置については、UX的に利用する場合があるので、あえてSetノードを置いているのも理由としてはあります。カーソル位置を覚えておく場合とか。

 

変数の関係と使用イメージを図にしてみました。見えている数が5個の場合です。

f:id:hiyokosabrey:20160913220312p:plain

この4つの変数(うち1つは定数)を使って表示範囲をコントロールします。

 

 必要な変数が用意できたので、カーソルの表示範囲チェックの部分を作ります。

また差し込んでいきます。

f:id:hiyokosabrey:20160913062605p:plain

カーソル位置 FocusIndex の値が更新された直後に判定します。

f:id:hiyokosabrey:20160913222427p:plain

あともう一息。

表示範囲を動かす処理です。

同じような内容が上と下につながるのでマクロにします。ListScrollと命名しました。

f:id:hiyokosabrey:20160913223637p:plain

スクロールする方向を指定するためのパラメータ(Integer型)を受け取れるようにしています。

ではマクロの中身はこうなっています。

f:id:hiyokosabrey:20160913224601p:plain

ScrollStepというFloat型の変数を作って置いています。これはスクロール移動量で、リストアイテムの高さと同じ値が入っています。これも定数になります。

 

 VerticalBoxのポジションをGetとSetしているとこで、見慣れない状態になっていると思います。これはピンを分解している状態です。

f:id:hiyokosabrey:20160913225044p:plain

 Split Struct Pin を選択するとFloat型に分解されるのです。Breakeノードを使わないのでスッキリです。

こういった分解できるものは他にもたくさんあるので、気になったら右クリックしてみるのをオススメします。

 

テストしてみましょう。

 

f:id:hiyokosabrey:20160913225623p:plain

ようやくらしくなりました。

あとは、矢印の表示くらいですが、長くなったので今回はこの辺で。

 

 

UMGでリストボックスを作ってみる

スクロール機能のついたリストボックスを作ろうと思って、ブループリントを触り始めたら思いのほか手間取ってしまいました。当たり前のように使ってるUIのしくみって作ってみないと分らないものですね。ちょっとボリュームがあるので、うまくまとまるか自信ないけど書いていきます。

 

ちなみに

UnityとかiPhone開発界隈ではスクロールビューとか呼ばれているみたいですね。

リストボックスで検索すると、Excelの画像がたくさん出てきます。

 

今回作ってみたのはこんな感じ。

f:id:hiyokosabrey:20160911112619p:plain

UMGには ScrollBox というものが用意されていますが、今回は VerticalBox(バーティカルボックス) を使います。

 

さて、そもそものリストボックスについておさらい。

表示しきれない量の選択肢に対応するための仕組みで、表示範囲が移動するのがポイント。

f:id:hiyokosabrey:20160911123740p:plain

 

今回ゲームパッド操作を考えているので、カーソルが存在します。カーソルが移動して表示範囲を越えようとしたときにようやく表示範囲が移動します。表示範囲内であればカーソルが動いても表示範囲は動きません。

つまり、カーソル移動と表示範囲の移動は完全には連動しません。

f:id:hiyokosabrey:20160911123722p:plain

こんなとこでしょうか。

UMGでこれを再現するために、CanvasPanel で表示範囲を決めて、VerticalBox をその子供にします。VerticalBoxを動かせば、CanvasPanelの外は描画されないので、バッチリです。

 

リストアイテムを作る

 リストとして並べるパーツを作ります。

コンテンツブラウザで Add New ボタンか、右クリックで User InterfaceWidget Blueprint を選択。

f:id:hiyokosabrey:20160911125515p:plain

 とりあえず WD_ListItem命名して編集開始。

シンプルに下敷きの板(Image)とテキストブロック(TextBlock)の2パーツです。

f:id:hiyokosabrey:20160911125918p:plain

テキストブロックに が入っているのは、ディセンダ(ベースラインより下の部分。小文字の g j p q y 用)の加減が分かるようにするためです。

さらにサイズを大きめに設定して、下敷きよりも下にハミ出させているのは、VerticalBoxで並べたときにスキマを作るためです。(VerticalBoxの設定でできそうなノードを見つけたのですが、まだできないっぽい)

テキストブロックは、内容を自由に書き変えたいので、変数化します。

Detailsタブの一番上にあるチェックボックスにチェックを付けます。

チェックボックス左のフォームは変数名として使われます。

f:id:hiyokosabrey:20160911141050p:plain

 

このリストアイテムは、カーソルの乗った状態(=フォーカス)と、乗ってない状態(=デフォルト)の2つがあります。

f:id:hiyokosabrey:20160911141833p:plain

 これをアニメーションで作ります。

f:id:hiyokosabrey:20160911142304p:plain

 これで見た目は完成。編集モードを Graph に切り替えます。

さっそく関数を2つ用意します。うえの2つのアニメーションを再生するためのものです。関数にしておけば、自分以外のブループリントなどから呼び出してもらうことができます。関数は、My Blueprintタブの Functions にある +ボタンをクリックして追加します。

中身は以下のようにつなぎます。まずは setDefsult 関数。

f:id:hiyokosabrey:20160911143958p:plain

ほぼ同じ内容で setFocus 関数。

f:id:hiyokosabrey:20160911144108p:plain

両方とも同じカラーを変更するタイプのアニメーションなので、安全のためにいったん先に動いているであろうアニメーションをストップさせてから、再生するようにしています。

 

 最後にテキストブロックの内容を変える仕組みを用意します。

以前の記事では関数を使っていましたが、今回は使いません。

代わりに変数を一つ用意します。タイプはテキスト型。

EditableExpose on Spawn にチェックを付けます。

f:id:hiyokosabrey:20160911145309p:plain

 

次に Event Graph を編集します。

初めから置いてあった、Event Construct ノードに変数化したテキストブロックをつなぎます。Set Textノードは、テキストブロックのGetノードから 「set」 と 「text」 で検索するとすぐに見つかると思います。

f:id:hiyokosabrey:20160911160342p:plain

 In Textピンにさきほど作った変数を接続。右端にデフォルトアニメーションを再生する関数をつないでおきます。UMGは最後に触った状態から表示を開始する仕様なので、強制的にデフォルト状態にしておけば安心です。

 

以上でリストアイテム完成です。保存して閉じます。

 

 

 リストを並べる

作ったリストパーツを並べて表示するための『親』Widgetを作ります。

今度は WD_ListBox と名付けました。

f:id:hiyokosabrey:20160911223740p:plain

まずはUMGでパネルをレイアウトします。

f:id:hiyokosabrey:20160911223626p:plain

レイアウトしたのは3つ。

 1.下敷き(Image)

 2.表示範囲用(CanvasPanel)

 3.リスト並べ用(VerticalBox)

 

3を2の子供にします。

f:id:hiyokosabrey:20160911224215p:plain

VerticalBoxだけ太字になっているのですが、これは変数化しているという意味を表しています。ブループリントから触るのはVerticalBoxだけです。

f:id:hiyokosabrey:20160911225007p:plain

 

追記: 2020/6/27

この記事を書いていた当時、CanvasPanel はデフォルトでクリッピング(キャンバスの外側にはみ出た部分は描画しない)してくれていましたが、最近は設定が変更になったようで、今回のような表示方法では、明示的にクリッピングするよう、設定を変更する必要があります。

f:id:hiyokosabrey:20200627203131p:plain

CanvasPanel にこの Clip to Bounds を設定すると、子供にしたVerticalBox は CanvasPanelの中だけに描画されます。

<<<

 

Widget命名ルールについて、

ちょっと名前が長くなるのですが、なるべく何のパーツかわかるようにアンダースコアの前の部分は残すようにしています。

 

 

これでUMGのレイアウトは完了です。

編集モードを Graph に切り替えます。

 

まずリストパーツに表示するアイテム名を作ります。

実際にゲームなどで汎用的に使う場合、他からリストを受け取ることになると思いますが、今回はテスト用に自前で用意します。ブループリントをスッキリさせたいのと、後から取り外しがしやすいので、マクロにします。

My Blueprint > Macros  の右端にある+ボタンをクリック。

Detailsタブの下の方にある Outputs のところにテキスト型の配列を追加します。

f:id:hiyokosabrey:20160911230806p:plain

グラフのノードも変化しているので、ピンからドラッグしてMakeArray ノードを取り出します。

f:id:hiyokosabrey:20160911231002p:plain

あとは Add pin+ を好きなだけクリックして、テキストを入力していきます。

 

できたら、このマクロを使ってリストを並べる処理を作ります。

タブを マクロから Event Graph に切り替えたら、作ったばかりのマクロを取り出します。このマクロは白いピンがないので、このままだとつながりません。

そこで ForEachLoop ノードの出番です。これは配列変数と相性抜群で、とても便利なノードです。配列の要素(中身とか引き出しのイメージ)の数に合わせて処理をしてくれます。要素が尽きると Completed ピンに流れます。

f:id:hiyokosabrey:20160911232327p:plain

さらに便利なのが、ArrayElement ピンです。つないだ配列の要素を順番に取り出してくれるのです。

普通の ForLoop ノードだったらこうなります。

f:id:hiyokosabrey:20160911232811p:plain

 

Loop Body は、繰り返し行う処理をつなぐためのピンです。

ここに CreateWidget ノードをつないで 『子』の リストパーツWidget を量産します。

f:id:hiyokosabrey:20160911233809p:plain

 

Classの部分に 『子』のWidgetをセットしたとたん、ノードの下部分 に新しくピンが出現します。Expose on Spawn した変数がここに顔を出すので、ForEachLoopのArrayElementピンとつないでやります。

 

新たに『子』としてCreateWidgetされたパーツは、後から個別にデフォルトとフォーカスを切り替えるので、配列変数にしまい込んでいきます。

まず、Return Valueピンの上で右クリックして、Promote to Variable を選択します。

f:id:hiyokosabrey:20160911235105p:plain

この操作で 『子』Widget型の変数が作られます。

f:id:hiyokosabrey:20160911235301p:plain

これを配列変数に切り替えるのですが、このままやると警告が出てちょっとイヤな感じなので、いったんグラフ上で消してしまいます。Variablesリストには残っているのでそこで設定と名前を変更します。

f:id:hiyokosabrey:20160911235718p:plain

この配列変数を、Addノードを使って CreateWidgetノードとつなぎます。

f:id:hiyokosabrey:20160911235941p:plain

 

最後にVerticalBoxに追加します。Variablesリストからドラッグ&ドロップして、Getで配置したら、Add Child to VerticalBox ノードを取り出して、下図のようにつなぎます。

f:id:hiyokosabrey:20160912002801p:plain

 ループ処理が完成しました。

 

仕上げにカーソルを表現します。

ForEachLoopノードの Completed ピンに 『子』Widgetで用意した setFocus 関数をつなぎます。

f:id:hiyokosabrey:20160912003823p:plain

この辺りで一度表示を確認してみます。

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

f:id:hiyokosabrey:20160912004211p:plain

再生してみると、

f:id:hiyokosabrey:20160912004355p:plain

見た目はほぼ完成です。

 

今回はこの辺までにします。

次回ひき続き動かす部分を作っていきます。

 

ではでは

 

Widgetコンポーネントにマテリアル

4.13にアップデートしてみたら、うれしい機能が追加されてた。

多分VRでWidget使いたいという声が多く寄せられたんじゃないかと想像してみたり。

Widgetはそのままだと、2Dだけど、とWidgetコンポーネントとしてWorld空間に置くと3次元が表示できる。DeadSpaceが再現できる。

ブループリントアクターから、Widgetコンポーネント としてビューポートに追加するんだけど、4.13からここにマテリアルがセットできるようになった!

f:id:hiyokosabrey:20160904211101p:plain

相変わらず Experimental(実験的)実装なまま・・・

 

マテリアル以外にも気になるパラメータがあるんだけど、とりあえずマテリアルで実験してみた。

適当な背景用画像を用意。

f:id:hiyokosabrey:20160904213625p:plain

で、これを使ってマテリアルを作成。SceneDepthを利用。

f:id:hiyokosabrey:20160904213710p:plain

Widgetに使うんだけど、コンポーネント用だとマテリアルドメイン(属性)は Surfaceでいいみたい。

ScreenDepth は、不透明モデルが描画されるタイミングで更新されるぽくて、そのDepth(深度)情報を元に if ノードで描くか描かないかを決めています。

 

次に、Widgetブループリントを作成。

といっても、上のマテリアルで適応するとWidget自身の描画がされないので、ひとまず四角い板を一つ。

f:id:hiyokosabrey:20160904214740p:plain

サイズは 適当に 1920x1080 。

SaveしてWidget完成。

 

次にブループリントアクターを作成します。

+Add Component ボタンから、Widgetコンポーネントを追加します。

f:id:hiyokosabrey:20160904215126p:plain

追加したら、エディタ右の Detailsタブを確認して、

Material という項目を探して用意したマテリアルをセット、

f:id:hiyokosabrey:20160904223631p:plain

すぐ下の User Interface という項目の、Widget Class に作ったWidgeブループリントをセットします。

f:id:hiyokosabrey:20160904215925p:plain

Draw Size に描画したい大きさを指定できるのですが、Widgetの中身に合わせてほしいので、Draw at Desired Sizeにチェックを付けておきます。

簡単なテストなんでブループリントはこのくらいで出来上がりです。

 

ではワールドに配置していきましょう。

適当なキューブとかスフィア(球)を置きます。ライトも適当に。

ブループリントもドラッグして配置します。右端がブループリントの中にいるWidgetコンポーネント

f:id:hiyokosabrey:20160904224930p:plain

これをWidget側に回り込むと・・・

f:id:hiyokosabrey:20160904225143p:plain

手前にいるのに、モデルより奥に描画されています。SceneDepth情報がうまく利用できているということです。

カメラに貼り付けたりビルボード的に表示できれば面白い使い方ができそうです。

 

4.13いいですね。

まだまだ検証しないといけないですが、また何か発見があれば記事を書こうと思います。

 

今回はこの辺で。

 

 

 

 

 

 

 

UIを作ることの難しさ

f:id:hiyokosabrey:20160828153229p:plain

UIを構成するのはデザインだと思っている人がいる。デザインなんてほんの1割程度だということを理解している方はどのくらいいるのだろうか?

 

UIは目で見て操作するタイプが多いので、見た目に誤解を招いたり、スムーズなオペレーションに誘導できない場合は、デザインやインタラクションで解決することになる。

機能要件を実装するためにロジックを組み上げ、ユーザー体験というストーリーボードを想像しながら、時間をかけて作り上げていく。

 

そこに「クオリティ」や「イメージ」をという名の武器で斬り込んで切る方がいる。

その「クオリティ」や「イメージ」で斬られたものが悪いもの(BAD UI)であれば良くなるのだけど、一方的な押し付けに近いなまくらで斬られると痛い上にロジックが破たんするので、立て直しに時間がかかる。

デザインを変えただけではうまくいかない。

 

ゲームのUIを作るという仕事は、庭を作るのに似ているように思う。

でもUIをデザインだと考えているひとは今すぐ花を用意して飾ればいいと言う。その飾り方にコダワレと言う。確かにその方が短期間でいい見栄えのする状態にすることはできる。切り花の展覧会ではないので、枯れたらおしまいというわけにはいかない。毎日その庭を眺めることになるのを踏まえて、飽きのこない手入れが少なくてもいい植生を考えることになる。でもそれを納得しない人がいるのも事実。

ゲームを起動して終了するまで、または一つのモードを何度も遊ぶようなプレイサイクルを考えると、UIはプレイヤーをストレスなく導くものであってプレイサイクルをジャマをしてはいけない。あくまでもUIは影の主役であって表に出てはいけない。


少し話は変わって、

家の敷地の角でよく見かけるナンテンの木について詳しく知っているひとは少ない。なにも知らなくても赤い実がキレイだなくらいの視覚効果はある。赤い実のなる木はいくらでもあるのに、なぜにナンテンなのか。そこにロジックが存在する。その理由を知らないで何かを植える話になった場合いくつかの選択肢が出てくると思う。

・なんかあちこちの家でナンテンを植えてるみたいだからナンテンでいいよ。

・赤い実よりもサザンカやツバキみたいな花がいい。

・いつでも実や花があるわけではないから一番キレイな状態の造花がいい。

・そもそも植える必要はあるの?何か別のオブジェを置いたら?

 

とまぁこんな感じで話をまとめるのに苦労しそうな予感しかしない。

実際ナンテンには微量の毒があって虫除け効果がある。赤飯なんかに葉が載せられているのはそのため。鳥も一度にたくさんは食べない。その方がフンが拡散するから。漢方薬にもなっていたり、名前の由来は「難を転じる」からとか、雪ウサギの耳に使う1枚の葉は、実はあれで1枚ではなく、100枚近くある小葉全体で1枚の葉だったり、調べてみると面白い話がいっぱい出てくる。

 

とまぁ、なんか文字ばっかり、理屈ばっかりになったけど、ちょっと憂さ晴らししたくなったのでこの場を借りて書き散らしてみた。もっといっぱい書きたいことがあるのだけど愚痴にしか聞こえないだろうからこの辺にしておきます。

明日から頑張ろう。