みつまめ杏仁

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

テキストブロックのスクロール 続き

前回の続きでスクロールバーを付けてみます。

limesode.hatenablog.com

 以外にサクッとできました。まずはUMGのパーツを追加するところから。

 

f:id:hiyokosabrey:20170220223725p:plain

スクロールバー全体の大きさを決めるキャンバスパネルを親にして、スクロールバーの下敷きとバー本体を表すImageパーツを子供にします。ちょっとだけラクをしたいのでバーの長さは、テキストブロックの表示サイズと同じにしています。

 

スクロールバーの長さを計算して変更する関数を追加します。

f:id:hiyokosabrey:20170220224608p:plain

このセットアップ関数は、テキストブロックの中身を変更する関数の中に置きます。

f:id:hiyokosabrey:20170220224816p:plain

スクロールバーを動かすためのマクロを用意。

f:id:hiyokosabrey:20170220225243p:plain

これをテキストボックスのスクロール部分にくっつけます。

f:id:hiyokosabrey:20170220230103p:plain

テキストボックスを動かす計算をしたあと、その値を拝借するカタチです。

以上で完成です。

 

不思議の国のアリス(英語)の冒頭を使って試してみました。

f:id:hiyokosabrey:20170220230446p:plain

f:id:hiyokosabrey:20170220230458p:plain

やっぱりスクロールバーはいいですね。あとどのくらいっていうのが判るのは大事です。

UMGにはとても便利な 『スクロールボックス』 が既に用意されているので、わざわざ苦労して作ることもないのですが・・・ こういった基本的なUIを自分の手で一回は作っておくのもいいと思います。試行錯誤してみて初めて仕組みの深いところが分かったり、当たり前のように毎日使ってるGUIの奥深さに気付くこともあるかと。

 

ではでは今回はこの辺で

ステキなスクロールライフを!

 

 

テキストブロックのスクロール

f:id:hiyokosabrey:20170218200852p:plain

 テキストブロックで、長文を表示しようとしたときに、たいていAuto Wrap Text(=自動改行)にすると思います。

f:id:hiyokosabrey:20170218203113p:plain

文字量が多いとサイズが大きくて表示しきれないので、スクロールさせるのが我々UI業界では当たり前の仕組みです。

 

UMG パーツ

f:id:hiyokosabrey:20170218220855p:plain

 まずはイイ感じの大きさのキャンバスパネルを置いて、その子供にテキストブロックとイメージを配置します。キャンバスは表示範囲を限定するためのものです。子供たちにとってこのキャンバスパネルが実際に表示される大きさになるので、アンカーの設定を右下のやつに設定します。

f:id:hiyokosabrey:20170218221511p:plain

スロットの設定は以下のようにすると、親のキャンバスパネルにピッタリフィットするように可変します。

f:id:hiyokosabrey:20170218221818p:plain

 Offset ~ は余白が欲しい時に設定します。

 

Event Construct

事前に取得できて後から再利用できる値は、なるべく変数化しておきます。

f:id:hiyokosabrey:20170219223957p:plain

 ここでは、見える範囲と一度にスクロールする量を求めて変数にしています。

 

 テキストブロックの中身を変える

 UMGのテキストブロックには、内容を変更する方法が3つ(他にもあるかも)用意されています。

1.テキスト型の変数に直接バインドしてしまう方法Flashみたいな)

  その変数の内容を書き換えるだけで反映されます

2.関数にバインド(紐づけ)して、その関数の戻り値を使う方法

  その関数にパラメータ(引数)を渡していろいろ加工することができる

3.バインドせずに setText ノードを使う

  エンジンが値を見張ることがないので処理の負担が軽い

 

頻繁に値が変わる場合は、1か2が向いていますが、今回作ろうと思っているのは内容がほとんど書き換わらないので、3にします。

↓テキストをもらって書き換える関数です。

f:id:hiyokosabrey:20170218224228p:plain

 ForceLayoutPrepassノードと getDesireSizeノードのコンビネーションで新しいテキストブロックのサイズを取得します。右端の関数は、親のキャンバスパネルのサイズと比較してスクロールするかどうかをチェックする関数です。キャンバスパネルに収まらなかった場合のみスクロールできるようにしたいので比較してフラグを立てます。

f:id:hiyokosabrey:20170219223606p:plain

ついでにスクロールの限界位置を計算して変数に入れておきます。

 

フラグが立ったら

 フラグといってもブーリアン型の変数です。それをEventTick に Branchノードでつないでやります。スクロールが必要ない場合は処理を省けます。

スクロールが必要な場合は、キー入力を受けてスクロール処理をします。

f:id:hiyokosabrey:20170219225459p:plain

入力チェックのマクロはこんな感じ。

f:id:hiyokosabrey:20170218233113p:plain

Was Input Key Just Pressed ノードは、EventTickのように細かく処理が流れてくるところにつないで使います。Get Player Controller ノードがないと使えないので注意。

ゲームパッドとキーボードのカーソルキーを両方扱えるようにしたいので、OR(論理和)ノードで判定してます。

関数は出口が一つだけど、マクロだと分岐できるのでこういった場合とても便利です。

スクロールするために用意した関数は3つ。スクロール量を計算する関数2つと、実際に動かすための関数になります。

f:id:hiyokosabrey:20170219230322p:plain

f:id:hiyokosabrey:20170219230331p:plain

最終的に、青いノード(Vector2D)に移動後の値(目的地)が入るようにします。

キー入力のたびに上の関数が呼ばれ目的地が瞬時にセットされます。で、常時処理されるのがこの関数↓

f:id:hiyokosabrey:20170219230803p:plain

目的地から現在地の差分に0.1を掛けて現在地に加算したものを新しいポジションとしてセットします。これで常に目的地に向かって移動し続けます。0.1は速度の調整用として掛けています。

 

完成

f:id:hiyokosabrey:20170219231224p:plain

 試しに、シャーロックホームズの冒険(英語)から”ボヘミアの醜聞” の冒頭を流してみました。いい感じにスクロールできます。フォントは Canterburyという書体です。

f:id:hiyokosabrey:20170219231545p:plain

 無事ちゃんと動いていますが、まだ先があるのかわからないので、UIとしてはまだ完全ではないです。スクロールバーか、▼表示か、好みが分かれるところです。あと、上下の端に辿り着いたときに、ループさせるか否かも悩ましいところです。ということで今回はこの辺にしておきます。

ではでは

ステキなスクロールライフを

 

【おまけ】小数点でハマった

最初1行ずつスクロールしていたのですが、行数が多くなると誤差が出てきたり、端までいったときの判定が難しかったりで、結局 固定のスクロール量にしました。それほど悪くないと思います。同じ値を足し引きしてるはずなのに、数値が 0.0000008 みたいなことになるので、< >を使った判定が思うようにいかず頭をかかえることに・・・

 

【補足】うまくgetDesireSizeで取得できない場合

 まだ原因がよくわかっていないのですが、UMGの編集を開始してからしばらくはタイミングによってはまったくサイズが取得できなかったり、改行する前のサイズが取れてしまうようです(私の環境のせい?)。

 そこで確実に改行後のテキストブロックのサイズが取れる仕組みを見つけようといろいろ接続を試してみました。EventTickにつないでチェックすると間違いなく取れます。

f:id:hiyokosabrey:20170218215800p:plain

 DoOnceノードを使って処理をしたりしなかったりをスイッチングします。

 (このあたりいじってたら、いつのまにか、なくても取得できるようになってました・・・)

 

 

UMGでよくやらかすやつ

最近カレンダーを見るのが怖い。

年が明け、あっという間に1月も残り1週とちょっと。ブログの更新もペースが落ちて前回から随分間が開いてしまいました。世間から忘れ去られないように頑張っていきたいと気合だけは入れているのですが・・・

 

 さてさて、今でこそ注意するように習慣ができてきたのですが、UMGでアニメーションを作っていて、いざ見てみようと再生すると、「え?」という状況によくなります。最初は原因が分からないので、エンジンの不具合か?などと人のせいにしたりして、「UMGワケわかんな~い。」とか聞こえないのをいいことにぷつぷつとぼやいていたものです。

 原因が分かれば怖くないのですが、これが原因でUMGをキライになる人が増えるのは不幸なのでメモ程度に書いておこうと思った次第です。

 必ず起こるわけではないのですが、起こりやすいのが、フェードやフレームIN/OUTのように最初は見えない系。このタイプのWidgetを表示したときに、一瞬だけ変なタイミングのアニメーションが再生されることはないですか?その解決策をご紹介します。

 

 普通にWidgetブループリントを作って、UMGのタイムラインでアニメーションを作って完成したらコンパイルして保存すると思います。このとき必ず儀式というかお作法のようにやった方がいいのが、アニメーショントラックリストのフォーカス外しです。

 アニメーションを作って確認していると、アニメーショントラックリストがフォーカスした状態になっています。このフォーカスを外してから保存することがとても重要なのです。

f:id:hiyokosabrey:20170122211605p:plain

(外すとオレンジ色の帯が消える)f:id:hiyokosabrey:20170122211811p:plain

この地味な操作は、アニメーションが一切再生されていない状態、つまりUMGのデフォルト状態を確認するためです。このデフォルト状態の確認を怠ると、Add to Viewportしたタイミングで「!」となるのです。

  デフォルトの状態と、最初に再生するアニメーションの0フレーム目が同じ状態ならバッチリなのです。

 

 フレームインだと画面外、フェードインだと完全に透明、というのがデフォルト状態になるので、レイアウト作業がしづらいです。そこでポジションを動かしていたり、アルファの値を 0以上にしていたりするのですが、そのまま保存して確認、「!」というパターンからなかなか抜け出せない自分に若干イラっとすることに・・・

そこで『フォーカス外し』なのです。すこしの手間ですが、これを習慣づけることでストレスは減った気がします。この操作でシステム的に解決するわけではないので、期待された方がいたらゴメンなさい。確認は自分の目でします。

 

ではでは

今年もよろしくお願いします。

ステキなUMGライフを!

 

 

 

 

アンリアルエンジン4を使いながら

 このブログも始めてから1年経ちました。どーせすぐ飽きるかなと思ってたけど、なんとか続けることができて今更ながら自分に驚いてます。これも素晴らしいエンジンに出会えたからに他ならなくて、ゲームユーザーインターフェイスの制作で少しでもお役に立るなら、アンリアルエンジンをステキなUI制作ツールとして周知させることができるんじゃないかという野望というか下心が原動力になっている気がします。

 

 実際デザイナーという肩書で、「UIの絵素材」を作り、エンジニアにこのパーツはこう動かして・・・これはこの時はこうなってて・・・まだ非表示で・・・UVが・・・。みたいな指示書や資料を作ってお願いしていたのが、UE4の登場で変わりました。

 

 UIデザインの仕事って軽く見られている気がするのは、単なる被害妄想ではないと思いたいのですが、画面に表示されるゲージなんて四角い選択範囲を塗りつぶしただけでできそうだし、数字なんてフォントを適当な位置に置いてるだけで、制御してるのはプログラムのおかげだし、配置やカラーにどんな意味やロジックが込められていようと見た目にカッコ悪いと、UIダサいとか言われるし・・・この辺のモヤモヤを一気に吹き飛ばしてくれたのがUE4です。

 

 まずは作ってみる。試してみる。最初はノードが怖くて変なつなぎ方したらヤバいことになるんじゃ・・・とビビリながらつないでました。多少はお作法みたいなものを身に付ける必要はあるけど、白い線をたどってノードを順番に追っていきながらアーでもないコーでもないと、今では作りたいUIはなんとかなる。というくらいの自信はつきました。

 ようやく書き上げた指示書を渡して、エンジニアに動かしてもらって「なんかヘン」って時に調整に付き合ってもらえるとありがたいんだけど、忙しい時期だと修正を頼むのも心苦しい。

 UE4だと、まずは自分でどうにかして狙った動作(プロトタイプ)を作ります。それを評価してもらって仕様に合ってない部分を確認したり、拡張性について共有しながら、ブラッシュアップします。アセットの管理についてはエンジニアのアドバイスをもらいながら準備を進めていきます。このとき作ったものを壊す勇気は必要です。作り直すときに新しい方法に気付くことがあります。

 

 GUI は様々なステータスや値をグラフィカルに表示し、ユーザーに視覚情報として伝える役割があります。その表示のためのステータスや数値の扱いはエンジニアと相談して受け取り方を決めます。デザイナーはその値をもとに「伝え方(見せ方)」をデザインするのです。

 こうしてできたモックアップは動く指示書としてエンジニアに渡せます。ゲームの部品として組み込んでもらってようやくひと段落です。あとは見た目や統一感などバランス調整をして仕上げていきます。

 今までは、ややこしいアニメーションや演出のタイミングの制御をエンジニアが引き受けてくれていたので、割とバグとは無縁でいられたけどUE4でできるとなると、デザイナが引き受ける流れに自然となります。面倒な指示書、頼みにくい調整が無くなった分、見た目の不具合については責任として乗っかってくる感じです。

 

 UE4はUIを開発するのに向いていると思います。手法を思いつくまでは悩むことも多いけど、大抵のインタラクションを作ることができるので、理想のUIを構築できる環境はすべて揃っていると今でも信させてくれています。ここまでフトコロの深いツールは他にないんじゃないでしょうか。まだまだ進化しそうなUMG。正直手放したくないです。世界中のUIデザイナーが「UE4で作らせろ」って声を上げてくれる日を夢見てこのブログも頑張って続けていこうと思う今日この頃です。

 EpicのUE4開発チームの皆様ありがとう。そして来年もよろしくお願いします。

 というわけで今年もあと1日。当ブログを見に来ていただいた皆様ありがとうございます。更新ペースは遅いですが、来年もよろしくお願いします。

 

ではでは

ステキはUE4ライフを!

 

f:id:hiyokosabrey:20161230235018p:plain

 

 

 

ストラクチャを使ってみる

前にEnum(いーなむ)を使ったリストメニューについて書きましたが、最近になってUser Defind Structureが便利なことに気付きました。

ストラクチャはプログラム界では《構造体》とか呼ばれているようで、Enumと同じように、アセットで管理できます。Enumと違って中にいくつでも変数を仕込むことができるので、使い方によっては、とても頼もしい存在になってくれそうです。

 

作り方は簡単。コンテンツブラウザからいつも通り右クリックして作れます。

f:id:hiyokosabrey:20161214012219p:plain

 

で生まれたのが下のアイコン。

f:id:hiyokosabrey:20161214012242p:plain

コンテンツアイコンには、New User Defined Structure とあります。

「新しくユーザーが定義した構造体」ということになるのでしょうか。

いい感じの名前を付けたら、編集ウィンドウを開いて、変数を追加していきます。

f:id:hiyokosabrey:20161215000309p:plain

上の例ではText型の配列変数を一つ追加しました。

Saveして閉じたら、このストラクチャを使おうとしているブループリントを開きます。

そこで変数を追加します。

変数を追加したら、型(VaribleType)を変更するのですが、リストの中に自分の作ったストラクチャが追加されているはずなので、それに変更します。

f:id:hiyokosabrey:20161216003656p:plain

下図はストラクチャの名前と変数名を "ListName" にした場合です。

f:id:hiyokosabrey:20161216003945p:plain

 

値を取り出す場合は、Breakノードを使います。

f:id:hiyokosabrey:20161215030933p:plain

ストラクチャだと配列が扱えるので、値を取り出すのも簡単。ForEachLoopとの連携も便利です。

 

他にもいろんな型の変数が扱えるので、マテリアルパラメータコレクションみたいな使い方も便利そうです。アセットなので、カラーを初期値として設定しておけば、いろんなブループリントで共有することができるので、カラールールを揃えるのも簡単。一斉に修正や調整ができて便利そうです。

f:id:hiyokosabrey:20161216005354p:plain

 

変数として扱えるということは、当然、値をセットすることもできます。

その場合、Makeノードを使います。

f:id:hiyokosabrey:20161223234728p:plain

アセットの中身が書き換わるわけではないので、普段の変数と同じように扱えばOK。ただ、SetとGet のカタチで直接触れないので、BreakとMakeノードの助けを借ります。

 

なんとなく便利そうなストラクチャですが、ちょっとだけ気を付けることがあります。

ストラクチャのアセットを編集すると、そのストラクチャを使用しているブループリントすべてが自動的にコンパイルされ、未保存の状態になってしまいます。新たに別のレベルを開くか、エンジンを終了しようとすると、ダイアログが出てきて保存するかどうか訊いてくるので、うっかりDon't Save を選ばないように。

 

そんなに使いどころは無いかもしれないストラクチャですが、また機会があったら試していこうと思います。

 

ここ最近時間なくて、これだけの文章書くのに1週間以上かかってしまった・・・

では

今回はこのへんで。

 

 

UV座標の計算をマテリアルでやらせると指定がラクチン

以前、マテリアルのパラメータ指定で細かい小数を扱っているのを、改良する記事を書きました。

limesode.hatenablog.com

今回はもう少しだけ発展させます。

 

 テクスチャの一部を切り出して使うには、UVの2つの値を扱うことになります。このUとV、2つの値を渡すには、Set Scalar Parameter Value を2つ並べるか、

f:id:hiyokosabrey:20161203211210j:plain

Set Vector Parameter Value の4つあるピンを贅沢に使うか、

f:id:hiyokosabrey:20161203211557j:plain

処理される時間を考えると、Vectorのように一度に値を渡せた方がいいけど、なんかちょっともったいない気もしてて、もっとスッキリできないかなと考えてたら思いつきました。(またもや前置きが長い)

 

配列変数はもう使いません。

その代わり少し計算が必要になります。

これも過去の記事で書いたのが参考になります。

limesode.hatenablog.com

この記事でグリッドに並べるための計算方法を説明しました。これをマテリアルに応用してみたのが下の図。

f:id:hiyokosabrey:20161203213953p:plain

パラメータノードは、スカラー型が1つだけです。見慣れないやつがいるかもですが、値を調整する部分は4か所です。

f:id:hiyokosabrey:20161203225113p:plain

しかも必要な数値は3つ。簡単に計算できます。

 

  テクスチャのサイズは ヨコ 512 タテ 256 の場合です。アイコン1つ分の大きさは 80x80 なので、UとVそれぞれのサイズは以下のようになります。

80 ÷ 512 = 0.15625

80 ÷ 256 = 0.3125

f:id:hiyokosabrey:20160918001757p:plain

必要な3つの数値のうち2つが確定しました。3つ目は並んでいる数です。

f:id:hiyokosabrey:20161203225644p:plain

横方向に6つずつ並んでいます。この並んでいる数を計算に使用することでアイコンのUV座標(場所)を割り出します。このマテリアルさえ完成すれば、ブループリントはプログラマ管理してもらって、マテリアルとテクスチャはデザイナーが管理すればいいという、とても素敵な座組みで作業を進めることが可能です。

 

これでアイコンを番号で指定して表示することができるようになります。

Blueprintから指定したアイコンに切り替えたいときに、set Scalar Parameter Value ノードが一つで済みます。

f:id:hiyokosabrey:20161203230549p:plain

 アイコンの種類を Int型で扱ってそのままFloat型にするだけというシンプルさと、UV値のことは忘れてもOKというのが魅力的です。配列変数のメンテやメモリも不要なのでプログラマも喜んでくれるはず。

 

ただし、このステキな方法にもリスクがあります。

UV座標をマテリアルで演算することになるのでGPU側の負荷になります。描画処理に余裕がない場合は控えた方がよさそうです。とはいえUIがガッツリ表示されている時はそれほどシビアな描画はしていないのがほとんどだと思います。

 

アイコン表示の切り替えでお悩みの紳士淑女のみなさま、ぜひこのマテリアルで計算する方法を一度ご検討されてみてはいかがでしょうか。

ではでは

今回はこの辺で

 

 

 

フォントのフチドリを試す

遅ればせながらようやく 4.14インストールできた。

なんといっても試してみたかったのが、フォントのフチドリ機能!

というわけでさっそくWidgetを作ってみる。

Designerモードで、Textblockを置いたところ。

f:id:hiyokosabrey:20161126120944p:plain

設定を確認してみると、特に変化は見られない・・・

f:id:hiyokosabrey:20161126121131p:plain

いろいろ開けていくとありました Outline Settings

f:id:hiyokosabrey:20161126121355p:plain

 

サイズとカラーをセットしてみるとこんな感じに。

f:id:hiyokosabrey:20161126121705p:plain

おおっこれは嬉しい!Epicさんありがとう!

 

私はてっきり、サイズ(太さ)を変えたりしたら、こうなるんじゃないかと期待していなかったのです。↓(同じものを8方向にずらして敷いているだけ・・・)

f:id:hiyokosabrey:20161126123005p:plain

 

一人で盛り上がりつつ、

次にアウトラインマテリアルを試してみます。

作ったのはこんな感じ。

f:id:hiyokosabrey:20161126123828p:plain

これをセットしてみます。

f:id:hiyokosabrey:20161126124010p:plain

どうやら「乗算」ブレンドされるようです。マテリアルのままの色を出したい場合は、フチドリのカラーは「白」にしておくのがベスト。

 

マテリアルドのブレンドモードは特に違いはないのですが、Additive(加算)だけは描画されなくなります。(相変わらず加算の対応がよろしくないです。Epicさんよろしく)

f:id:hiyokosabrey:20161126125618p:plain

Opacityにノイズ入れてみたらこんな感じ。

f:id:hiyokosabrey:20161126125128p:plain

 

これにドロップシャドウを足してみましょう。

f:id:hiyokosabrey:20161126125911p:plain

ドロップシャドウというか、もう一つ色違いのテキストブロックが描画されているだけですね。ドロップシャドウにもフチドリがつきます。

 

Separate Fill Alpha というチェックボックスがあったので試してみました。

f:id:hiyokosabrey:20161126131242p:plain

アルファ値を「文字とは別」にするよ。というフラグのようで、

文字のアルファだけを0.0にすると下のようなこともできます。

f:id:hiyokosabrey:20161126131108p:plain

Photoshopのレイヤーの塗り(%) で調整するのと同じ見た目が作れます。

気を付けないといけないのは、フチドリのサイズと文字のカーニングです。上図のxとtのところのように重なってしまいます。

あと、Separate Fill Alpha にチェックを付けると、フチドリと文字の間にスキマができるのが若干気になりますが、この機能はスバラシイです。

 

 

しばらくいじっているうちに、下のようなのができました。

f:id:hiyokosabrey:20161126134217p:plain

 テクスチャは使っていません。

ドロップシャドウのアルファ値は、0.0にすると、フチドリが消えてしまうので、0.001 というほとんど透明で見えない値を入れています。

 

このフチドリにマテリアルアニメーションを入れてみました。

f:id:hiyokosabrey:20161126181339g:plain

↑GIFアニメで 700KB弱あります。

この動くフチドリをON / OFF すれば、カーソルフォーカスの代わりとして使えそうです。アニメーションのキーを打てないようなので、切り替える方法は今のところ思いつくのは2通り。フチドリのアルファ値を変えるのと、マテリアルのパラメータを変更する方法。

フチドリのアルファ値を変えるのは下のような感じでできた。

f:id:hiyokosabrey:20161126195049p:plain

一度今のフォント設定を取り出したら、OutlineSettingsのとこだけMake FontOutlineSettingsノードで作った値に差し替えて戻します。

 

マテリアルで変える場合は下のような仕込みをしておいて、

f:id:hiyokosabrey:20161126195411p:plain

マテリアルインスタンスダイナミックにしてアウトライン設定で差し替えておきます。

f:id:hiyokosabrey:20161126201109p:plain

あとは普通にSetScalarParameterValue ノードでいじるだけ。

f:id:hiyokosabrey:20161126201457p:plain

ひと手間かかりますが、パラメータを扱うときにスッキリします。

ちょっとキャプチャのコマを節約したので、ぎこちないですが動かすと下のような感じになります。

f:id:hiyokosabrey:20161126204251g:plain

 

どうでしょうか。

まさかここまでできるとは思ってもみなかったので、すごくウレシイです。

改めて、Epicさんありがとう!

 

つぎは、マイターの種類が選べるようになるとか?

 

 ではでは今回はこの辺で

ステキなフチドリライフをぜひ!