みつまめ杏仁

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

ぷちコン振り返り

暑さが少し和らいだ気がしなくもないですが、確実に日暮れが早くなっているので地軸の傾きを実感しています。

 

残念ながら紹介されるまでには至らなかったですが、先日応募した第14回ぷちコンの簡単な振り返りを書きます。

 

今回のぷちコンの参加は、あまり集中して時間が取れなかったのもあって見送る気でいたのですが、締め切り前告知をツイッターで見た直後にネタが降ってきて心残りもあったので、急いで作ってみた次第です。

f:id:hiyokosabrey:20200913003737j:plain

 


【第14回UE4ぷちコン作品】タイトル長いので省略

 

 夏休みといえば宿題。遊びたい誘惑を振り切ったと思いきや、すぐに切れる集中力。遅々として進まなかった苦い記憶がふっと思い出されたので、この集中力をタイマーにしつつ、逼迫した状況に抗うゲーム。というイメージが浮かびました。

 

RollingTemplate をベースにしています。

 

  • 見えてる範囲を狭くしたい
  • おやつ食べて回復したい
  • いろんな誘惑がステージに置いてあって近づくと集中力が激減する
  • 集中力がなくなってくると徐々に視界の周りがざわざわする
  • レイマンの動きで状況を説明。飽きさせない動きにしたい

 

というのを最初考えていましたが、さすがに期限が目前すぎて猶予がなかったのでできる範囲で作りました。

後からこちらの記事を読んで、 練度の違いを実感。

paviliondv7.hatenablog.com

トルク制御を知っていればもっといろいろできたかもしれない予感。

勉強勉強。

 

 

 

BPのつながりについて

参考になるかわかりませんが、作例としてBPの構成をご紹介。

 

f:id:hiyokosabrey:20200914194335p:plain


 

GameStateクラスが全体の進行管理を担って、適宜HUDへの指示をします。

UI周りはすべて HUDクラスに一任しています。

 

このスタイルが結構気に入ってます。GameState と HUD には、ちゃんと調べたことはないですが、ほとんどのブループリントからアクセスすることができるのが理由です。

 

f:id:hiyokosabrey:20200912142522p:plain

自分の作ったやつにキャスト(型変換)しないといけないですが、頻繁にアクセスするのがわかっている場合は、変数化しておくとノードのつながりがスッキリしてグラフが見やすくなります。

 

GameState は状況の変化を感知したり、タイマーを動かしたりしています。画面表示に更新が必要になると、この GameStateから HUD に用意したカスタムイベント経由で値を渡します。

HUD は 画面のWidgetたちをすべて管理するようにしているので、受け取った値を表示しているWidget に流します。

 

UI表示までが少し遠い印象ですが、値の流れるルートが把握しやすく、改造が楽だったり、デバッグしやすかったりします。

複数人で作る場合、HUD と Gametate とで分担がしやすいのではと思うのですがいかがでしょうね。

 

 

視界について

集中すると周りが見えなくなるのをイメージして、スコープを除くような感じにしたかったので、最初 UMGのブラーエフェクトパネルを使ってみたのですが、ボケ具合がイマイチだったので、メインカメラの DOF を有効にしました。

f:id:hiyokosabrey:20200912202714p:plain

UMGだとガウシアンな感じがしてちょっとエモくない。

f:id:hiyokosabrey:20200912202723p:plain

DOFだと絞り羽の形がエモい。

 

中央のはっきり見えている部分はレンダーターゲットテクスチャ。

キャプチャ用のカメラを、メインカメラの子供にアタッチ。

f:id:hiyokosabrey:20200912203316p:plain

画面中央だけでいいので、レンダーターゲット用テクスチャのサイズは大きいとメモリ消費が厳しいので1024x1024 。 1080p だと上下に若干届かないくらい。

あとはこのテクスチャをマテリアルで抜いてUMGで配置するだけ。

f:id:hiyokosabrey:20200913105045p:plain

 

集中度合いをみて視界の大きさを変動させたりしたかったけど時間がなくて断念。

 

集中力がなくなってくると徐々に画面にノイズが重なってくるようにした。

f:id:hiyokosabrey:20200912204556g:plain

 

 

レーダーについて

今回実装に一番悩んだ部分。

f:id:hiyokosabrey:20200912205512j:plain

表示位置の計算は、座標から角度を得る atan2 を使って、UMG上で三角関数使えば戻せるなと考えていたけど、問題なのはどうやって散らばったオブジェクトを把握するか。

レーダーに映るのは一番小さなBallのみで、大きいBallにぶつかって分解されることでスポーンする仕組み。結構数が増減するので配列に動的に積むのはやめたほうがよさそう。ということで、マップにセットした大きいBallから総スポーン数を割り出して、最初から全部を配列で管理することにした。

f:id:hiyokosabrey:20200912214240p:plain

マップには 大きいBallを宿題7科目分置いたので、7×32 = 224個

一番小さいBallがスポーンする際に固有のID番号を渡すようにして、プレイヤーが触れたらそのID番号をバックしてDestroyするようにした。表示のOn/Off はBoolean型の配列を同様に管理して、スポーンしたら true 、いなくなったら false にする。

これをアクターとGameState 間でやり取り。

GameStateは常にスポーンされてるアクターの座標とプレイヤーの座標から角度を計算してFloat型配列を更新し続けていて、レーダー表示用のWidgetは、その配列から角度を取り出して表示に使うという流れ。

 

f:id:hiyokosabrey:20200913102051p:plain

 

 atan2(アークタンジェント)関数を使うと、

f:id:hiyokosabrey:20200913102110p:plain

XY座標と原点を結ぶ直線の角度(=傾き)を計算してくれます。

 

f:id:hiyokosabrey:20200912224018j:plain

今度は角度と半径、2つの値から、サインコサインを使って原点からのXY座標を計算します。あとは画面表示の際のズレを補正してやるだけ。ここがそこそこ面倒だったりする。

 

このレーダーの実装でそれなりに遊べるようになったので良かった。

これがなかったら、ストレスが溜まるだけだったので正直応募を諦めていたと思う。

 

 

レイマンについて

ちゃんとモーションつけて再生したかったけど、さすがに にわかでサクッとできる気がしなかったので、ポーズだけつけてアニメーションアセットを作った。

指を一本一本曲げていくのは意外に楽しくて、手の形でもかなり表情というか感情を出せるということに改めて気づけたので、グレイマンのように顔がノッペラだとなおさらいい勉強になりそう。グレーマンを使ったグラビアコンテストなんかも面白いかもしれない。完全に日本だけのコミュニティしかウケないだろうけど。

 

撮影用のレベルを作ってそこで適当にライトを置いて、解像度キャプチャーツールで撮ってテクスチャにしました。

 

 f:id:hiyokosabrey:20200913005337p:plain f:id:hiyokosabrey:20200913005345p:plain

 

キャプチャして立ち絵にするあたりは、ちょっとしたテクニックがあるので、また改めて記事にしようと思います。

 

 

 

カリキュラムのカウントアップについて

散らばった一番小さいBallには、0~223 の固有のID番号を振るようにしています。

最初マップに配置する一番大きいBallには 0~6の番号を与えておきます。

f:id:hiyokosabrey:20200913110009p:plain

それぞれがActorでプレイヤーと接触すると2番目の大きさのBallを自身の周りにスポーンさせて自身はDestroyします。

この2番目の大きさのBallをスポーンさせるとき、自身の番号に 32を掛けてさらに +0、+8、+16、+24 を加算して持たせます。

f:id:hiyokosabrey:20200913111511p:plain

さらにここから一番小さいBallが 8個 スポーンします。ここはシンプルに自身の番号に0~7の数字を加算しています。ForLoopノードのIndex値を加算するだけです。

 

f:id:hiyokosabrey:20200913112404p:plain

これで最終的にゲットするBall に固有のID番号振る仕組みができました。

今度はあちこちに散らばってしまったBallから、どのカリキュラムのBallかを逆算していきます。ゲットした番号を 32 で割ります。Integer型の割り算なので少数以下は切り捨てられます。

その値を配列を使ってカウントして、画面の棒グラフに反映しています。

カリキュラムが一つMAXになると、集中力の低下がしばらくストップするようにしました。宿題が一つ片付いたので勢いがつくイメージ。

 

 

 

 タイトルロゴについて

まぁゲームが地味なので、タイトルロゴくらいは賑やかにしようと思って頑張ってみました。テーマ回収をここでしてる感がありますが・・・ぶっちゃけあります。

f:id:hiyokosabrey:20200913004339p:plain

 

無理やりラノベ感を出そうとしてちょっと痛々しさも感じつつもう少し手を入れたいと思う自分がいたり。というわけでちょこっとコントラスト上げてみた。

 

f:id:hiyokosabrey:20200913115544p:plain

 

濃ゆくはなったけど、まだまだ追いついてない感じです。

 

 

 

諦めたこと

ブラックホール的な誘惑ゾーンを作りたかった。エンジンで床に凹みを作ろうとスタティックメッシュのブーリアンを試してみたのですが、UVのスケールを調整しきれなかったのと、エッジを滑らかにできなかったので、DCCツール使わないと無理そうと分かったので断念。

とにかくエフェクト。分解するときにパーティクルを飛ばしたかったけど、普段からエフェクトツール触ってないのもあって、手が止まってしまった。なんとか回復アイテムを取った時だけ出すことができた。前回もエフェクトを思い通りにできなかったのに解決できていないのがまったく反省していない。

 

 

 

 

 

最後に

結果発表の中で、「締め切り駆動」という言葉が何度か出てきて、今回まさにそれだと思いました。実際の仕事ではそんな状況を作ると叱られてしまうのですが、今回は短い時間でのチャレンジがとても楽しかったです。ぱっと思いついてさっと作ってみる。そんな炭酸の泡のようなアイデアでも、無謀にも一人で試してみようと思えるアンリアルエンジンのハードルの低さは素晴らしいです。そこそこ長く触ってきていますが、エンジンを触ること自体のハードルは決して高くないと思います。エンジンの開発およびサポートされている皆様には感謝しかありません。正直使いこなすのにそれほど時間がかからないと思うUE4ですが、厳しい現実と向き合わされることになります。

それは、自分自身が持つゲーム作りの感性。例えば、素晴らしいキッチンと調理道具がそろっている状況で、おかずのレパートリーが少ないのはなぜか?というのを考えると分かりやすいかもしれません。油を熱したことがなければ揚げ物やアヒージョなんて作ろうと思わないと思う。でも食べて感動したら試したくなるじゃないですか。しかも同じ環境、同じ道具で作らてしまうなんて、と。

と言いつつ自分はなかなか試せていない現実が重かったです。

そう考えると ぷちコンはとてもいい環境です。ぜひこのまま続いていってほしいですが、作品数が増えると審査にかかる時間と労力は相当なものになると思います。お忙しい中本当にありがとうございます。

 

次回はエモいの作りたいな・・・

 

 

ではでは

ステキな ぷちコン ライフを!

 

 

 

 

斜めになったメニューボタンでも~後略 《いろいろ試す編》

当ブログでは、CEDECで取りあげられることのない、ゲームUI開発で明日使えるかもしれない小ネタを主に扱っています。ためになるかもしれないし、ならないかもしれません。

 

さてさて

最近、斜めになったボタンでもマウスカーソル(ポインタ)を検出できるかという検証をしました。

limesode.hatenablog.com

 今回はその続きというかおまけのようなものになります。

 斜めに傾けるのはUMGの RanderTransform で設定できるのですが、その名の通り描画時にゴリっと変形させてしまう手法で、アンチエイリアスなど気の利いた処理が入りません。

エッジが見事にジャギってしまいます。解像度が高くて画素が小さいディスプレイだと気づかれにくいですが、背景の色との組み合わせで目立つこともあります。

f:id:hiyokosabrey:20200905160211p:plain

 

このジャギー対策はやはりテクスチャで解決するのが簡単なので、専用のテクスチャを用意します。サイズは 128x128px

f:id:hiyokosabrey:20200905163208p:plain
RGBAの各チャンネルを分解すると ↓ このようになってます。

f:id:hiyokosabrey:20200905163633p:plain

  ※上の画像をDLするとPhotoshopで再構成できます

 

UIパーツは状況に合わせてカラーを変えたりすることが多いので、いちいちバリエーションを用意してたらテクスチャ容量が厳しくなります。そこでできるだけテクスチャに頼らない方法として、このスタイルが最近のお気に入り。

Photoshopで作る場合、各レイヤーのブレンドは、覆い焼き(リニア)-加算  です。

この方法だとマテリアルが必須になってしまうのですが、調整の手軽さや複数人での開発を考えるとコスパはかなり高いと思います。

 

f:id:hiyokosabrey:20200905164902p:plain

 

カラーをどういじるか次第でノードのつなぎ方は変わってはきますが、この程度のノードでボタンの色味は自由自在です。マテリアルパラメータコレクションを使えば、リードUIデザイナーがカラーを一括して調整するのが簡単にできます。複数人で開発する場合それぞれが自身のPhotoshopでカラーを共有管理しながら作業するのは、うっかりや伝達漏れなど、そう簡単ではないと思います。これだけネットワーク環境とゲームエンジンが進化しているのであれば、プラットフォームやデバイスの多様化と能率のことも考えると、ある程度ゲームエンジンという一つの大きな作業台の上でデザインを仕上げていこうという考えはそう悪くはないと思うのです。

 

このへんちょっと意味わかんないと言われてしまうとアレなんで、オーソドックスだけどマテリアル使う方法も紹介。

テクスチャはこのように2種類の絵を一枚にまとめておきます。256x128px

f:id:hiyokosabrey:20200905215909p:plain

※上の画像をDLすると PNG形式なのでそのままインポートできるはず

 

f:id:hiyokosabrey:20200905220828p:plain

この方法だと2種類の絵を Lerpノード使ってスイッチすることができます。

マテリアルを使わずに作る場合 あらかじめ2枚の絵を重ねておいて、上に乗っている方のアルファ値を操作する方法が普通。2枚のオブジェクトが必要になるうえに、アルファで半透明の部分が重なって濃くなるので、フェードアニメーションするたびに輪郭が太ったり痩せたりします。試しにデバッグ用のノードをつないでみましょう。

f:id:hiyokosabrey:20200905222021p:plain

Lerpノードの Alpha につなぐだけで簡単に確認できます。

f:id:hiyokosabrey:20200905222255g:plain

背景が黒なので溶けてわかりにくいですがテクスチャのアルファ値は変化していないので輪郭の濃さは変わりません。


ちなみに2枚重ねだとこうなります。

f:id:hiyokosabrey:20200905224730g:plain

まぁこの程度は気にしないか気付かない人がほとんどだと思いますが・・・

 

この青とオレンジの2パターンは、通常時とハイライト時に切り替える予定です。

 

となると、先に紹介した方はUMGのアニメーションでカラーを変化させる方法になります。

f:id:hiyokosabrey:20200905164902p:plain

ただ、この方法はプロジェクト全体で一括調整というのが難しいのと、CPU負荷も少し気になるので、マテリアルパラメータコレクションに変更します。ということで、最初のマテリアルをもう少しいじっていきます。

まずコンテンツブラウザからマテリアルパラメータコレクションを新たに作成。

f:id:hiyokosabrey:20200906102736p:plain

編集して4色を用意します。カラーは RGBAと4種類の値がひとつにまとまっているので Vector Parameter を選択します。

f:id:hiyokosabrey:20200906103257p:plain

これを組み込んでいきます。

マテリアルエディタのグラフで右クリックして CollectionParameter ノードを取り出し、

f:id:hiyokosabrey:20200906104123p:plain

Detailsタブからさっき作ったマテリアルパラメータコレクションをセット。

f:id:hiyokosabrey:20200906104109p:plain

これらをLerpで補間してやります。

f:id:hiyokosabrey:20200906104701p:plain

Lerp(線形補間:Linearinterporate)も処理コスト的にそんなに安くないので、ここはカーブアトラスを使った方法も試してみます。
カーブアトラスとカラーカーブについてはこちらの記事がおすすめ。

historia.co.jp

で用意したのはこの2本。

f:id:hiyokosabrey:20200906105608p:plain

これを組み込んでみます。

f:id:hiyokosabrey:20200906105928p:plain

 すっきりコンパクトになりました。

ちゃんと負荷検証をしたわけではないので勝手な推測になるのですが、カーブアトラスを置くためのメモリ容量を犠牲にしてでも、カラーのアニメーション計算の方が処理付加的に高くつくからというのが、その存在理由なのかなと思ってみたりしてます。事前に計算した変化の度合いをテクスチャに焼き付けておくことで計算を省力化してるのかなと。

ただ正方形テクスチャで非圧縮だと思われるので、テクスチャ容量に余裕がないプロジェクトは厳しい手法になりそうです。なのでカーブアトラスを使うと決めたらめいっぱいカラーカーブを仕込んでいきたいですね。

 

 

マテリアルはこの辺にしておいて、ボタンWidgetを作っていきます。

UMGでキャンバスに Image を配置。先ほど用意したマテリアルをセットします。

TextBlockも配置してキャンバスはこんな感じで構成。

f:id:hiyokosabrey:20200906112708p:plain

前回の記事で書いたように左右のスキマ調整用に SizeBox で Wrapしています。

f:id:hiyokosabrey:20200906113018p:plain

ここに、マウスカーソル(ポインタ)のヒット検出用に Image を重ねます。

f:id:hiyokosabrey:20200906113806p:plain

半透明で色を付けた状態で作業して、位置と形が決まったら完全に半透明にします。

f:id:hiyokosabrey:20200906114227p:plain

f:id:hiyokosabrey:20200906114238p:plain

Hierarchy はこのようになりました。

f:id:hiyokosabrey:20200906114410p:plain


次にアニメーションを追加します。

アニメーションはボタンのマテリアルに用意していたパラメータに対して付けます。

f:id:hiyokosabrey:20200906115545p:plain

 

トラックが追加出来たら今度はそのトラックにマテリアルのトラックを追加します。

f:id:hiyokosabrey:20200906115852p:plain

f:id:hiyokosabrey:20200906120038p:plain

ここでようやくプロパティが追加できるようになります。

f:id:hiyokosabrey:20200906120359p:plain

あとはキーを打つだけ。

f:id:hiyokosabrey:20200906121039p:plain

このアニメーションは 通常時(デフォルト状態)用で状態をリセットするために使うので特に尺は必要ないので、キーはひとつだけ打ちます。最初に5秒分の尺が設定されているので、終了点を詰めます。※ゼロにはできないようです。

 

次に ハイライト用のアニメーションを作ります。

こちらは尺を0.25秒でキーを打ちます。キーの値は 0.0 ~ 1.0 

f:id:hiyokosabrey:20200906122000g:plain

 

とりあえずアニメーションはこの2つ。

次はマウスカーソル(ポインタ)が重なった時に呼び出されるイベントがあって、その検出をスムーズに行うために、Visibility(ビジビリティ) の設定を変更します。

Visibility は Behavior(ビヘイビア)の中にある設定項目です。

最後に追加した ヒット検出用の Image 以外を Non-Hit-Testable(Self Only) にします。

f:id:hiyokosabrey:20200906132915p:plain

あとはTextBlock の isVariable を有効にしておきます。

f:id:hiyokosabrey:20200906133519p:plain

キャンバスの準備ができました。

 

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

マウス用のイベントをオーバーライドします。

前々回の記事でも説明しましたがもう一度載せます。

f:id:hiyokosabrey:20200815160501g:plain

f:id:hiyokosabrey:20200815160829p:plain

~Enter と ~Leave の2つを取り出します。

f:id:hiyokosabrey:20200815160933p:plain

ここに 作ったアニメーションをつなぐのですが、アニメーション管理用の変数を追加します。

VariableType は Widget Animation型

f:id:hiyokosabrey:20200906135732p:plain

 

これを使ってマクロを作ります。

グラフ内である程度つないだら、選択して 右クリック > Collapse To Macro を選択。

f:id:hiyokosabrey:20200906140151p:plain

f:id:hiyokosabrey:20200906140345p:plain

これをダブルクリックして編集します。空のマクロから作成しても問題ありません。

実行ピンがつながってないので、ノードからドラッグして追加します

f:id:hiyokosabrey:20200906141138p:plain

Inputs と Outputs のノードにドロップすると、自動で実行ピンが追加されます。

f:id:hiyokosabrey:20200906141646g:plain

 

f:id:hiyokosabrey:20200906141809p:plain

 

このマクロを経由してイベントとアニメーション処理をつなぎます。

まずは On Mouse Enter から

f:id:hiyokosabrey:20200906143204p:plain

 

次は On Mouse Leave

f:id:hiyokosabrey:20200906143328p:plain

 

残るはテキストの変更する処理。

Integer型の変数を一つ追加して、外部から値を受け取れるようにします。

f:id:hiyokosabrey:20200906165704p:plain

Expose on Spawan と Instance Editable を有効にします。

 

この変数を、Event Pre Construct で使います。

f:id:hiyokosabrey:20200906165859p:plain

 

マウスオーバーしか機能はないですが、これでボタンのWidgetは完成です。

 

 

確認用にボタンを配置する 親のWidgetを新しく用意します。

キャンバスに HorizontalBox を一つ置いたら、作ったボタンWidgetを並べたいだけ置いていきます。

UE4はプロジェクト内に作った Widget は、User Created というカテゴリにエントリーされるようになります。CanvasPanel や TextBlock、Image をPaletteタブから取り出すようにこのリストから取り出せます。フォルダが違えば同じ名前のWidgetが作れるので、適当に作ってるとこうなります。マネしないようにしましょうw

f:id:hiyokosabrey:20200906171507p:plain

なんとか探して、Hierarchey の HorizontalBox にドロップします。

f:id:hiyokosabrey:20200906172151p:plain

↑5つばかり置いてみました。

 

ここ面白いのが、先ほど ボタンWidgetで作った Integer型の変数にアクセスできるところ。

追加したボタンWidgetを選択した状態で、 エディタ右にある Detailsタブを見てみると、ここから値を設定できるようになってます。

f:id:hiyokosabrey:20200906172728p:plain

f:id:hiyokosabrey:20200906173039p:plain

値を書き換えるだけで、コンパイルしなくてもどんどん変わっていきます。

f:id:hiyokosabrey:20200906173056p:plain

これはなかなか面白い仕様です。

 

これで完成です。

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

動画はツイッターに上げました。

 

 

前回の記事では、ブループリントから動的にボタンUIを生成しましたけど、今回は手で並べてみました。変動せずに決め打ちで作れるならこの方法でも大丈夫だと思います。

決定処理とか作り始めると、また長くなるので今回はこの辺にしておきます。

 

UIの表現は、見た目は同じでも作り方としていろんなアプローチがあって、正解というかベストを探る感じで作ることが多いです。UE4はいろんな方法を試せるのでとても楽しいです。

UI制作において作り方マニュアルが欲しいという話をチラホラ耳にしますが、欲しかったらまずはUIを作ってみるのが一番の近道だと思います。この辺いい感じのアドバイスができないのが個人的に口惜しく感じているところではありますが、おっとまた長くなるところでした。

 

ではでは

ステキなUI制作ライフを!

 

 

 

 

 

斜めになったメニューボタンを並べてみる《テスト編》

前回のつづき

f:id:hiyokosabrey:20200815200712g:plain

検証もできて満足したので、そのまま選択するとこまで作ってしまおうと勢いづいて作り込んでみました。

あらかたできた時点でTwitterに上げたのですが、このブログで記事にしていく途中で、いろいろ足りてないところを発見。不具合を直したりあれこれ触っているうちに、気が付けば それなりに機能の入ったメニューUI ができていました。

ゲームの UI は状況と仕様に合わせて柔軟に作っていくものなので、あくまでも一例として参考程度に流し見してくださると助かります。

 

いろいろメンテナンスとか、融通の利く作りを考えてたら、このようなアセット構成になりました。

f:id:hiyokosabrey:20200823122830p:plain

今回の記事では、とりあえず並べてボタンのアイコンとラベルをテスト表示するところまでを書こうと思います。

 

ひととおり動くやつをGoogleドライブにアップしましたので、興味のある方はこちらをDLして触ってみてください。

 

drive.google.com

 

 

 

さてさて

 最終的に扱うWidgetは前回作ったのと、今回作る2つ。

f:id:hiyokosabrey:20200823234129p:plain

命名が適当・・・)

 

 

ひとまず並べるための新しいWidgetブループリントを用意します。

前回の記事で作ったボタンWidgetを 子とするなら それを管理する 親Widget になります。

 

キャンバスに HorizontalBox を一つ、ドラッグ&ドロップします。

f:id:hiyokosabrey:20200823121833p:plain

 

画面中央に配置します。

f:id:hiyokosabrey:20200823001953p:plain

正確に中央に置くためには、ターゲットになるプラットフォームの解像度を調べて計算してもいいのですが、ここは アンカー と アライメント を利用します。

 

キャンバスの適当な位置にドラッグ&ドロップして、Anchors の設定を変更します。

f:id:hiyokosabrey:20200823002652p:plain

ついでに Is Variable にもチェックを付けて有効にしておきます。

このチェックは ブループリントから触るためです。

 

Position Xゼロ にして、Alignment X0.5 にすると 画面の中央に配置されます。

f:id:hiyokosabrey:20200823003135p:plain

Size To Content にチェックを付けます。

これは 内容物に応じて自動的にHorizontalBox のサイズが変動するようにするフラグです。

有効にすることで、Alignment の効果も効いて、常にセンタリングされるようになります。座標計算しなくていいし簡単!ありがとうUE4

 

 

この HorizontalBox に ボタンWidgetを並べる方法は2つ。

あらかじめキャンバスにある程度の数を配置してしまう方法と、ブループリントで必要な数のみ動的に配置する方法があります。

 

事前にキャンバスに置く場合↓

f:id:hiyokosabrey:20200823142511p:plain

ゲームの仕様によりますが最大数を8個としています。初期表示設定 は Collapse で。

 

Widgetブループリントから動的に必要な数だけ生成する場合 ↓

f:id:hiyokosabrey:20200823142456p:plain

 

 

試しにこの2種類のWidgetを用意して Reference Viewer で確認してみるとどちらも同じ構成でした。(下図は 動的配置した場合のもの)

f:id:hiyokosabrey:20200823140531p:plain

 

となるとWidgetのViewport配置時のスパイクが心配になるので、何度か再生してみた。

f:id:hiyokosabrey:20200823140655p:plainあらかじめ追加する方法は、保険の意味もあって8個分 Collapse の状態で仕込んでおいて、必要なボタンだけを表示してアクティブにしています。実際に表示するのは6個。こちら再生するたびにピークが上下するので、ちょっと不安定な印象。

一方のブループリントから動的に生成する法は安定して同じカーブになる印象。

GPU(黄色いライン)にわかりやすく差が出ました。 環境やらプロジェクトによって同じになるかわからないのと、検証の方法が合ってるか自信がないので情報をお持ちの方はそのあたりを共有していただけると嬉しいです。

 

ということで、ひとまず動的に生成する方法について書いていきます。

 

ブループリントから、他のWidgetアセットを生成するのは、

Construct Object from Class ノードを使います。

f:id:hiyokosabrey:20200823212423p:plain

このノードは名前が変わるので、スクショでの説明が難しいやつです。

取り出した直後 ↓  Object~ が NONE(設定無し)になっています。

f:id:hiyokosabrey:20200823212816p:plain

前回の記事のWidgetをセットしたところ ↓

f:id:hiyokosabrey:20200823213432p:plain

 

このノードで召喚されたWidgetが Return Value から出てくるので、あとはそれを HorizontalBox に子供として追加します。

この流れを ForLoop ノードで表示したい数ぶん繰り返せば並びます。

f:id:hiyokosabrey:20200823232741p:plain

 

前回の記事で、レベルブループリントで簡単な表示テストをつなぎました。

そこの Create Widget にセットしたWidgetを 親Widgetに差し替えます。

f:id:hiyokosabrey:20200823233743j:plain

 

再生してみると並んでいるのが確認できます。

f:id:hiyokosabrey:20200823233023j:plain

 スキマもいい感じでバッチリ。

 

 

 

さすがに味気ないので、ボタンのアイコンやラベルを管理する部分を作っていきます。

 

ゲームのメカニクスやプレイサイクルなどは、なかなか最初から完成しているというのは少なくて、やっぱりスクラップ&ビルドによって育てていくのがゲーム開発の常です。特にUI は遊び方が変われば、そっくり作り直しなんてこともしょっちゅうです。デザインを差し替えるだけならまだましですけどね。

よし遊びができたぜ! となっても今度は、ゲームの進行に合わせてUIが変化する仕組みも必要になることがよくあります。キーアイテムを拾ってない、まだレベルが解放されていない、魔法を覚えていない、などなど。最初から見せるのもモチベにはなりますが、たいていはネタバレになってワクワクが減るし、解放された感を無駄に強めにアピールする必要があったり、また情報が多いのでUIの学習コストが高くなります。

というわけで、選択肢の数と状態、並び順をコントロールできる仕組みを考えてみました。

 

ストラクチャ(User Defined Structure)を用意します。

アセットブラウザで右クリック > Blueprints > Structure を選択します。

f:id:hiyokosabrey:20200824234507p:plain

f:id:hiyokosabrey:20200824234704p:plain

 ダブルクリックすると専用のエディタがポップアップします。

New Variable ボタンをクリックして必要な数の変数を定義します。

f:id:hiyokosabrey:20200824235023p:plain

今回用意したのは以下の4つ

 

 ID ・・・ 選択肢の内容を特定するための管理番号 Integer型

ItemLabelText ・・・ ボタンのラベル名 Text型

IconIndex ・・・ アイコンの絵を指定するIndex番号  Integer型

isEnable ・・・ 有効か無効のフラグ Boolean型

 

必要最小限だと思いますが、あとはお好みで。

 

 

次にアイコンテクスチャを用意します。

解像度が256x256px で アイコンひとつの大きさが 64x64pxです。

f:id:hiyokosabrey:20200825000602p:plain

これも最初からデザインと並びがきっちり管理できていれば問題ないですけど、やはり途中で意味が合わなくなって使わなくなったり、追加で増えたりするので、並び順と管理番号が噛み合わなくなることがよくあります。テクスチャ容量も有限ですし、欠番を空けたままというのも勿体ない話。なので、ここはデザイナー都合で並べることにします。

 

これをインポートして Grayscale テクスチャにします。

f:id:hiyokosabrey:20200825001853p:plain

インポートできたら、このテクスチャからマテリアルを用意します。

アセットブラウザのアイコンの上で右クリック > Create Material を選択。

f:id:hiyokosabrey:20200825002547p:plain

f:id:hiyokosabrey:20200825153951p:plain

マテリアルエディタが開きます。

 

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

f:id:hiyokosabrey:20200825002925p:plain

アイコンの大きさは一律なので、TexCoordノード(赤いやつ)の Tiling 値はUとV共に 0.25を入れてあります。

 

ブループリントからアイコンのIndex番号のみを受け取って計算するようにしています。もしGPUの負荷をちょっとでも減らしたい場合は、ブループリントの方でUV座標を用意して渡すようにします。

f:id:hiyokosabrey:20200825004020p:plain

 

今回は、マテリアル内で計算するタイプを採用します。

 

このマテリアルを、ボタンWidget の Imageパーツにセットします。

f:id:hiyokosabrey:20200825154757p:plain

f:id:hiyokosabrey:20200825154145p:plain

セットする場所は、Appearance の Brush のところに アセットブラウザからマテリアルをドラッグ&ドロップするとセットできます。

f:id:hiyokosabrey:20200825154303p:plain

 

ボタンの状態をアニメーションで用意します。

尺はなくて、色をけるだけのキーがあるだけです。

f:id:hiyokosabrey:20200825163701p:plainf:id:hiyokosabrey:20200825163711p:plain

f:id:hiyokosabrey:20200825163725p:plain

以下の2つはアニメーションをつけています。

まずは決定時の余韻。

f:id:hiyokosabrey:20200825163752g:plain

選ばれなかった未練。

f:id:hiyokosabrey:20200825163806g:plain

 

変数を5つほど追加。

f:id:hiyokosabrey:20200825201444p:plain


 

変数を用意できたところで
ボタンをセットアップするためのカスタムイベントを用意します。

 

f:id:hiyokosabrey:20200825202407p:plain


Inputs にピンを2つ追加します。ひとつは用意したストラクチャの型を選択。

f:id:hiyokosabrey:20200825202330p:plain


ストラクチャ → f:id:hiyokosabrey:20200824234704p:plain

 

この追加したピンからドラッグして、Breakノードを取り出します。

f:id:hiyokosabrey:20200825202534p:plain

 

このBreakノードで、中の変数に対して個別にアクセスできるようになるので、受け取った値を処理していきます。

f:id:hiyokosabrey:20200825210613p:plain

最初の始めのほうにあるInteger型の変数はここで保存しておいて、決定処理をした際に親のWidgetに通知するときに使います。

右端のブランチノードはBoolean型の変数 isEnable が false のときに DISABLE のアニメーションを再生するようにつなぎます。基本 true なので、false のときだけ処理します。

 

作ったアニメーションを再生するためのカスタムイベントを用意します。

f:id:hiyokosabrey:20200826233935p:plain

下段の2つは、ボタンをクリックした後のイベントになります。

 

決定時だけいつもと違う再生ノードを使っています。

f:id:hiyokosabrey:20200826234122p:plain

これは最近のUE4で追加されたノードで、アニメーションの再生終了を待って処理を行いたいときに便利です。ここでは、イベントディスパッチャーをつないで、親Widgetにアニメーション終了を通知しています。


クリック処理は onMouseButtonDown という関数をオーバーライドして作成しますが、ちょっと判定がややこしいので今回は説明を省きます。

 

ボタンWidget(子)はいったんこの辺にしておきます。イベントディスパッチャーやフラグの取り扱いは、コンテンツをダウンロードして確認していただけると助かります。

次に、親Widgetを編集していきます。

f:id:hiyokosabrey:20200827003333p:plain

まずは変数を新たに2つ用意。

f:id:hiyokosabrey:20200827003359p:plain

デバッグ用にマクロを用意します。DebugButtonDataと命名

f:id:hiyokosabrey:20200827004334p:plain

ボタンを6個分用意しています。

左のでっかいノードたちは、順番に取り出していくとスムーズに取り出せます。

まずストラクチャ型の変数(あらかじめ配列にしておく)を Set のかたちで取り出します。その左のピンから、ドラッグして "make" で検索。Make Array ノードを見つけて取り出します。Add pin + ボタンを必要な数だけクリックしてピンを増やします。

今度もそこからドラッグして "make" で検索。 Make menuButtonData を選びます。

あとは複製(Ctrl + W)

 

f:id:hiyokosabrey:20200827081802p:plain

このMakeノードを配列に入れた数が画面に並びます。そこで数を調べて変数に保存します。

f:id:hiyokosabrey:20200827082203p:plain

 

このマクロをボタンを並べるForLoop の前に置きます。

ボタンを生成する部分を改造します。

f:id:hiyokosabrey:20200827083836p:plain

それぞれ並んだボタンをブループリントから処理するために、ボタン型の配列を作ってセットしています。

作り方は Construct ノードの Return Valueピンからドラッグして Promote to variable を選択。

f:id:hiyokosabrey:20200827084446p:plain

できた変数を適当にリネーム。今回は Buttons と命名。(複数形にすると配列であることがわかりやすい気がする)

Details(詳細)タブ から、配列に変更します。

f:id:hiyokosabrey:20200827084432p:plain

 

右端の部分。

f:id:hiyokosabrey:20200827085335p:plain

Widgetの持つ関数やイベントにアクセスするには、Construct ノードの Return Valueピンからドラッグして検索すると出てきます。 このときUE4のエディタを英語環境にしていると、"call" で簡単にリストアップできます。

f:id:hiyokosabrey:20200827085717p:plain

具体的な名前を憶えていなくてもこれで探せるので私はこのために英語環境にしているといってもいいくらいです。

 

試しに再生してみます。

f:id:hiyokosabrey:20200827212953j:plain

レイマン イイケツしてんな~

ではなく、無事アイコンとラベルがセットできました。

並べ替えや追加も簡単です。

f:id:hiyokosabrey:20200827213124j:plain

 

さて、あとは入退場の動き作って、クリックされたら決定して、また次に備えて・・・

という流れを作っていくことになります。

汎用性とか柔軟性とか拡張性、そういったことを考えるとUIの実装難度はどんどん上がっていきます。さらに仕様バグが出やすくなるのでチェックコストも増えます。手間やら気遣いやらを考えると、作る側はあまり報われないのがUIなのかと、つい思ってしまいます。おっと目から水が・・・

とはいえ、ここっていうタイミングでそっとハンケチを差し出すようなUIが作れたら、それこそが UI 作ってて良かった、という喜びみたいなもので心が満たされるのです。

 

ひとまず、記事ではここまでの解説にしようかと思います。

なかなかのボリュームにもかかわらず読んでいただきありがとうございます。

途中で放り出しやがってけしからん!という方は以下のリンクからダウンロードして、お使いのUE4のプロジェクトフォルダの Content/Developers フォルダに解凍すると、エンジンで触れるようになるはずです。Verは 4.25.3 です。

drive.google.com

 

クリックすると下のようなポップアップが出ますが無視して問題ありません。

f:id:hiyokosabrey:20200827221552p:plain

 

不明な点や不具合等あれば、ブログのコメント欄かTwitterにてツッコミいただければ対応します。


ではでは

ステキなメニューライフを!

 

斜めになったメニューボタンでもマウスに反応するか試してみた

COVID-19のなんやかんやで緊張しながら日々過ごしていたらもうお盆の時期。心なしかセミの声も元気がないような気もする。近所の田んぼでは稲の穂もチラホラ見えはじめたのでまた花粉に苦しむことになる予感・・・。

 

先日 Twitterで、シアーで傾けたUIでもマウスオーバーを検出できるのか気になって試してみた、というのを呟きました。

f:id:hiyokosabrey:20200812114405p:plain

動画はここ ↓ で確認できます

 

 

試してみようと思ったきっかけは、今までの体験が元になっています。

こういったナナメのデザインを作ると、

矩形の範囲で検出する方がコストが安く時間がかからないのに、なんてデザインしてくれるんだ、とプログラマに渋い顔をされたものです。

 

f:id:hiyokosabrey:20200815133948p:plain

 

インハウスツールの場合、ツール開発者がよほど暇にならない限りデザイナーの気まぐれに先回りするような人はいないのが普通だとは思います。

さてUE4はどうかな~? フォートナイトでも見たし、大丈夫だろうきっと。

というわけで試して出来上がったものを記事にします。

 

 

用意したWidgetは2つ。

 

まずは子のWidgetから用意します。

 UMGのキャンバスに 下敷きとなる Image を置いて、手前にアイコン用の Image とラベル用の TextBlock を置きます。

f:id:hiyokosabrey:20200812161457p:plain

 ヒエラルキーは以下の状態

f:id:hiyokosabrey:20200812161857p:plain

ここで下敷きの Image に Shear(シアー)を適用します。

f:id:hiyokosabrey:20200812162146p:plain

 

f:id:hiyokosabrey:20200812162259p:plain

 アイコンとテキストの位置がおかしくなるので整えます。

 

 

Hierarchyに最初から置かれている CanvasPanel を SizeBox でラッピングします。

CanvasPanel で右クリックして

Wrap With ... > SizeBox を選択

f:id:hiyokosabrey:20200812163045p:plain

この操作で、CanvasPanel 以下を SizeBox の子供にします。一つ上の階層を増やして包むイメージで「Wrap」。

f:id:hiyokosabrey:20200812163713p:plain

この階層構造をやめたいときは、SizeBox のところで右クリックして

Replace with ... > Replace With Child を選択 するとSizeBoxはいなくなります。

f:id:hiyokosabrey:20200812225255p:plain

最上階のものはドラッグしても入れ替えができないようです。

 

ここからSizeBoxの調整をします。

UMGの編集用エリア(ビジュアルデザイナ)右上にあるボタンを切り替えます。

f:id:hiyokosabrey:20200812230046p:plain

Desired か Desired on Screen にします。

これは描画の際のアスペクト比、解像度によるスケーリングをシミュレーションしたりしていろんなデバイスによる差を確認しながら、レイアウト作業をするためのスイッチです。

この 子Widgetの場合、並べるのは別の 親Widgetになるので、レイアウト作業としては画面に対してではなく、パーツ同士の位置関係まで、ということになります。

 

わかりやすくするために SizeBox(またはCanvasPanel) を選んだ状態で切り替えてみます。

f:id:hiyokosabrey:20200812231202p:plain

「Desired」 は 「望まれた」 という意味合いなので、ここでの使い方としては

  《 UE4は、SizeBoxの大きさとしては、このように認識しているよ 》

という程度の理解で大丈夫だと思います。

 

この子Widgetを 並べる際に、SizeBox の持つサイズが、 利用されることになります。

f:id:hiyokosabrey:20200812235526p:plain

( ↑ 表示イメージ )

今の状態のままだと、左右にスキマがないのでくっついてしまいます。

後からでも調整できるのですが、編集の流れで行ったり来たりすると説明がややこしくなりそうなので、スキマの空け方を書いてしまいます。

ひとまず左右に 5 ずつ 空けることにします。

 

まず、SizeBoxはポジション等のSlot(Canvas Panel Slot) を持たないので、位置を変えることはできません。なので、中のImageパーツたちを移動させます。今回右に(X方向) +5 移動させました。フォームの値に +5 を追記してEnterキーを押すと加算してくれるので便利。

f:id:hiyokosabrey:20200813001813g:plain

CanvasPanel の Render Transform で 移動させるとまとめて移動できて簡単ですが、移動アニメーションを考えるときにややこしくなるので、できるだけRender Transformは触らないでおきます。編集時のバウンディングボックス(点線の四角)が増えてしまうのも回避できます。後々の修正・調整のためにできる限りシンプルなデータ作成を心掛けたいものです。

f:id:hiyokosabrey:20200813001124g:plain

中のパーツが右に移動した分、SizeBoxの幅が少し大きくなりました。

左に余白ができたので、今度は右側にも余白を足します。

ここで、SizeBoxの出番です。

今のSizeBox の幅を調べて、そこに +5 すればOK。

さて困りました。どうやってSizeBoxの幅を調べたものか・・・

 

いくつか試した方法があるのでメモとして残しておきます。

 

調べ方その1 Get Desired Size ノードで調べる

一旦 画面に表示して get Desired Size ノードを使うと精確な値が取れます。

SizeBoxの is Variable にチェックをつけておいて、グラフに下のようなノードをつなぎます。

f:id:hiyokosabrey:20200813003553p:plain

Delayノードは確実に値を取るための保険です。値が取れればこのノードたちは不要になります。

 

適当に新規レベルを作成してViewportに描画。

f:id:hiyokosabrey:20200813004003p:plain

PrintString が教えてくれます。

f:id:hiyokosabrey:20200813004019p:plain

 

ブループリントに慣れててもちょっと面倒に感じます。

 

次はちょっと特殊な方法。

 

調べ方その2 マテリアルで調べる

先日ツイートしたネタを使います。

 

このマテリアルは プロジェクトに1個作っておいて損はないやつです。

f:id:hiyokosabrey:20200813005408p:plain

TexCoordノードのIndex を3 にして使います。

f:id:hiyokosabrey:20200813005610p:plain

このマテリアルを、CanvasPanelの下に チェック用の Image を一つ追加して適用します。確認出来たら捨てるか非表示にしておくといいです。

f:id:hiyokosabrey:20200813005935p:plain

表示順は一番手前。

アンカーをストレッチにしてスキマなく広げます。

f:id:hiyokosabrey:20200813010106p:plain

この Image パーツに マテリアルをセットすればOK。

テクスチャをセットするところにマテリアルをセットできます。

f:id:hiyokosabrey:20200813010231p:plain

ただ、この方法で気を付けないといけないのが、表示倍率。

f:id:hiyokosabrey:20200813010612p:plain

Zoom が 1:1 (等倍) = 本来のサイズ になります。

 

この方法のいいところは、 マテリアルをセットしたImageパーツを追加するだけで、すぐに確認できるというところです。ブループリントを編集しないのでコンパイルの必要がありません。

 

 

調べ方その3 地道に探る

SizeBox の持つパラメータに、Max Desired Width というのがあります。

f:id:hiyokosabrey:20200813011517p:plain

ここに値を入れていって、これ以上変化しなくなる最大値をみつけます

 

最初に100とか200っみたいな値を入れてから、マウスで増減させます。

キャンバスの緑のラインが動くので、それが止まるところが最大値になります。

f:id:hiyokosabrey:20200813012522g:plain

ラインの変化が止まったらマウスをすぐに止めます。ここからは手入力で少しずつ探っていきます。

・・・

208 を 207 に変更。 ラインは変化しない。

207 を 206 に変更。 ラインは変化しない。 

206 を 205 に変更。 ラインは変化しない。

205 を 204 に変更。 ラインが動いた。

ということは 204 を 205 に変更。 ラインが動いた。

さらに 205 を 206 に変更。 ラインは変化しない。

 

ということでめでたく 205 という値をゲット! なかなか気の長い話です。

 正直頭のいい方法かどうかは気になるところですが、余計なパーツを追加したりしないので、アセットはピュアな状態のままです。

 

 

 

とりあえずこの3つくらいしか思いつかなかったです。
他にいい方法があるかもなので、教えていただけると嬉しいです。

 

で、この 205 に +5 した値が最終の表示サイズになります。

これを SizeBox の 持つパラメータ Width Override にセットします。

f:id:hiyokosabrey:20200813013658p:plain

これで左右に余白が生まれました。

f:id:hiyokosabrey:20200813013936p:plain

( ↑ 表示イメージ )

 

キャンバスの役者が揃いました。

 

ここからはマウスカーソル(ポインタ)が乗った時の処理を作っていきます。

 

まず、どういった見せ方にするか考えます。

ふるまいとして求められるのは、

 

  • マウスカーソル(ポインタ)が乗っていることをわからせたい
  • 決定時の演出とは違う見せ方をしたい

 

このあたりで十分だと思います。

アクションゲームなどは、プレイ中にノンビリできないので、できるだけ目立つ動きで誤操作を起こさないように表示するのが大事です。またマウスカーソル(ポインタ)やゲームパッド操作の場合、選択肢をどれにしようかな~って迷うことができるのも特徴になるので、カーソル的なハイライト表現も重要な表示要素です。もちろん決定時の表現も大事なフィードバックなので、決定前と決定後のメリハリを考えることになります。

 

いろんな作り方があるのですが、今回はマテリアルを使ったカーソル表現をやってみます。

ヒントになったのはこちらのツイート。

 

枠線を点滅させることにします。

f:id:hiyokosabrey:20200813233218g:plain

( ↑ イメージ )

 

マテリアルはこんな感じ

f:id:hiyokosabrey:20200815123425p:plain


部分を拡大しつつ説明していきます

 

まずは枠線を描く部分。

f:id:hiyokosabrey:20200815123616p:plain



任意の太さの枠線を描画サイズから割り出しておいて、カスタムノードで判定し塗分けています。

 左端のTexCoordノード(Uを押しながらクリック)は Detailsタブから Indexの値を 3に変更します。

f:id:hiyokosabrey:20200814214847p:plain

次(右側)の TexCoordノードは デフォルトのまま使います。

 

赤いサムネイルのノードは カスタムノードです。

HLSLのシェーダーコードを自前で用意して使うことができます。

詳しくは公式ドキュメント↓

Custom 表現式 | Unreal Engine Documentation

と、こちら↓のエントリー

pafuhana1213.hatenablog.com

カスタムノードは Detailsタブをいじっていきます。

f:id:hiyokosabrey:20200814215821p:plain

入力を3つに増やします。

Code のところに シェーダーコードを書きます。今回書いたのはこれです。

 

float f = (float)(Value>=Min)? 0 : 1;
float s = (float)(Value<=Max)? 0 : 1;
return (f+s);

 

? は 文字化けではなく 三項演算子ってやつです。ExcelVBAだったら Then に相当します。 : コロンはさしずめ Else ってとこですね。

オレンジ色は 入力ピンの名前です。fとsはなんとなく First とSecond です(適当)

UE4のフォーム内で改行する場合は、 Shift + Enter です。

もっと良い書き方がありそう・・・どなたかご教示いただけると嬉しいです。

 

で次は点滅部分

f:id:hiyokosabrey:20200815123904p:plain

Time に 大きい数値を掛けると点滅が速くなって、0.5 など小さい値を掛けると ゆっくりになります。

ConstantBiasScaleノードは、一定の幅を持った値に対して、調整するときに便利なノードです。

 

計算結果から想像するにたぶん中身はこんな感じだと思います。

f:id:hiyokosabrey:20200814231040p:plain

 

サインカーブは基本的に -1.0 ~ +1.0 の幅で変移するので、これを 0 ~ 1.0 の範囲に収めておかないと、マイナスの値の時に見た目がおかしくなりなります。(正規化とかNormalize とか言います)

Detailsタブから値を調整できますが、取り出したままつなぐだけで OK。

 

最後は、枠線の合成と着色する部分。

f:id:hiyokosabrey:20200815124356p:plain

Addの後の Clampノードは 値が 1.0をオーバーしないようにしています。

f:id:hiyokosabrey:20200815135800p:plain

f:id:hiyokosabrey:20200815201706p:plain

 

真ん中あたりの BlinkFlag というScalarパラメータを掛け算しているのは、ブループリントから枠線の有り無しをコントロールするためです。

 

ピクセルのカラーやアルファを扱う場合、OnとOff をコントロールするのに簡単なのが ゼロとイチ(= 1.0)を掛けることです。

ゼロを掛けるとカラーの場合は黒く、アルファの場合は透明にできます。今回カラーを Lerp(Linear Interpolate)で着色するので、枠線の部分がゼロになることで、見た目に枠線は消失します。

一方 1.0 をかけると何も変化しないので、スイッチの代わりになるということです。

 

0~1.0 の範囲 の 値が流れてくるのを、 Lerpノードが着色します。

Alphaのピンから入ってきた値が、0なら A のカラー。 1.0 なら B のカラー。

0.5 なら AとB の中間のカラー。 という風に、AとB2つのカラーを線形補間した値が出力されます。今どきのお風呂場にはたいていついてると思いますがお湯と水をブレンドできる混合栓みたいなやつのイメージ。Photoshopだとグラデーションマップが近いです。

 

 

このマテリアルを、UMGのキャンバスに戻ってベースのImageパーツにセットします。

f:id:hiyokosabrey:20200815150828p:plain

 

 

この辺でWidgetブループリントを編集します。

 

まず、マテリアルにアクセスするために、ダイナミックインスタンスマテリアルを用意します。

f:id:hiyokosabrey:20200815153350p:plain

 ReturnValueピンから ドラッグして、 Promote to Variable(変数に昇格) を選択します。

f:id:hiyokosabrey:20200815154046g:plain

MID_Base命名

 

次に この ダイナミックインスタンスマテリアルを使ってマテリアルのパラメータをいじる関数を新しく用意します。

f:id:hiyokosabrey:20200815154325p:plain

Select系のノードは、 型ごとにいろいろ用意されています。マテリアルのパラーメータは Scalarを選んだので、Select Float ノードを選択。Bool値(TrueかFalseのどちらか)によって分岐するように値を出し分けることができます。

その結果を Set Scalar Parameter Value ノードに渡します。

 

Selectノードを使わない場合はこうなります↓

f:id:hiyokosabrey:20200815155027p:plain

個人的にSelectノード使う方が、調整と修正がラクに感じるのでよく利用します。

関数名は switchBorderBlink命名

 

次に、マウス用のイベントをオーバーライドします。

f:id:hiyokosabrey:20200815160933p:plain

使うのはこの2つ。

Enter はマウスカーソル(ポインタ)が乗った時、Leave は離れたときに呼び出されるイベントになります。

 

最初から用意(ビルトイン)されている便利なやつですが中身がないので、上書き(オーバーライド)して使います。

 

2通りの取り出し方があります。

 

ひとつめ

Functions の Override ボタン(隠されてる)から探す方法。

f:id:hiyokosabrey:20200815160501g:plain

f:id:hiyokosabrey:20200815160829p:plain

 

 

ふたつめ

右クリックして検索する方法。

f:id:hiyokosabrey:20200815160702p:plain

Add Event > Mouse の中に カテゴライズされています。

 

 

取り出せたら、用意しておいた関数をつなぎます。

f:id:hiyokosabrey:20200815162120p:plain

片方のBool型のピン にチェックを付けたら準備完了です。

 

ひとまずテスト用のレベルで確認してみます。

適当に New Level を作って、Widgetを表示します。

f:id:hiyokosabrey:20200815180637p:plain

Create Widgetノードをとりだして、表示したいWidget をセット。ReturnValue ピンを Add to Viewport ノードにつなげば表示されます。

マウスカーソルを常時表示したいので、まず Player Controller ノード を取り出します。そこから Set Show Mouse Cursor を取り出して、True にします。

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

 

f:id:hiyokosabrey:20200815200712g:plain

 

表示されている位置が左上になってしまいますが、ちゃんと動作しているのがわかります。

素晴らしいですね。どういう作りになってるのかわかりませんが、それなりに頑張ってくれていると思います。

 

せっかくなので、セレクトメニューとして見せられるとこまでを書いていこうと思うのですが、結構長くなったので今回はこの辺までにします。

 

ではでは

ステキなマウスオーバーライフを!

 

 

 

 

 

UMGでマテリアルアニメーション制御 2020

蝉の声はまだ数が数えられるくらいしか聞こえてこないけど、確実に夏に向かっていることを感じます。この時期なると現れるジャンボタニシの卵塊を見るたびに、早く駆除されてほしいと願いつつ、アクセントカラーはいくら綺麗な色でも場所を選ばないとダメだなと改めて強く思う今日この頃です。またひとつ自然から学ばせてもらいました。

さてさて

UE4Widgetブループリント は独自のアニメーションタイムラインを持っています。配置したWidgetパーツに対して動きをコントロールする以外に、オーディオの再生、タイミングを見て関数を呼び出すEventTrack、マテリアルパラメータコレクションの値を制御といったものが用意されています。

f:id:hiyokosabrey:20200712104038p:plain

 

最近 この Material Parameter Collection Track の有効利用方法を考えていて思いついた一つが、パターンアニメーションのコントロール

基本構造のイメージが先で、いい見せ方ないかな~と考えていろいろやっているうちに結構日が経ってしまった。

Twitterに貼った動画がこれ。

 

見た目にワールドフリッパーのタッチエフェクトのモロパクリです。再現方法をいろいろ悩みつつ試していたら、なかなか複雑でよくできてるなと感心させられました。ランダム要素を入れつつもきちんと制御するところはされていて、アーティストとプログラマの仕事の境界が大変気になります。アーティスト比重が高ければ素晴らしいツールを使えていることになるので、それはそれで羨ましいし、逆にプログラマ比重が高ければ、アーティストとプログラマの協業レベルがとても高くないとできない仕事で、そんなプログラマとタッグを組めるアーティストが羨ましい。

 

てなわけで

今回の内容はマテリアルパラメータコレクションを使ったアニメーション制御ということで、複数のWidgetパーツを、ひとつのアニメーショントラックを共有して動かすという方法になります。

とりあえず基本的な構成をメモとして残しておくことにします。

 

必要なアセットはだいたい4つ

  • アニメーションパターンをアトラス化したテクスチャ
  • マテリアルパラメーターコレクション
  • Widget用のマテリアル
  • Widgetブループリント


今回テクスチャを節約したかったのでグレースケールテクスチャを採用。色付けにカーブアトラスを使ってます。

 

 

アニメーションを作る

パターンはPhotoshopで作りました。

f:id:hiyokosabrey:20200712150109p:plain

タイムラインパネルから、フレームアニメーションモードに切り替えたら、レイヤーをアニメのセルに見立ててモリモリ描いていきます。

f:id:hiyokosabrey:20200712150707p:plain

各レイヤーを順番に表示する、しないを切り替えるだけの単純なアニメーション。

f:id:hiyokosabrey:20200712150642g:plain

サイズは 64x64px。
512pxのテクスチャに収めたかったのと、キリよく8パターンにしたかったので、

f:id:hiyokosabrey:20200712150939g:plain

これだけだと、MaterialParameterCollectionを使う楽しみが少ないな・・・と考えてたところに ワーフリ と出会ったのでした。

同じ要領でもう2種類、パターン数の違うのを作りました。

f:id:hiyokosabrey:20200712151921g:plain ←4パターン (128x128px)

f:id:hiyokosabrey:20200712151930g:plain←5パターン (102x48px)

 

このパターンズを1枚のテクスチャにアトラスとして並べます。

f:id:hiyokosabrey:20200712152121p:plain

これをUE4にインポートします。

重要な設定が3つあります。

ひとつは タイリング設定。

f:id:hiyokosabrey:20200713230844p:plain

テクスチャを繰り返さない Clamp にしておかないと、パターンが終わらなくなります。

2つめは MipMap、3つめはTextureGroupです。

f:id:hiyokosabrey:20200713231326p:plain

基本 UI にミップマップは不要です。テクスチャグループもUIに設定するので、ミップマップが作られることはないと思いますが、明示的に NoMipMapsを選択しておきます。

 

マテリアルパラメーターコレクションを作る

f:id:hiyokosabrey:20200712175328p:plain

f:id:hiyokosabrey:20200712175539p:plain

マテリアルパラメータコレクションはプロジェクト全体で利用できるので、管理しやすいように名付けます。

 

f:id:hiyokosabrey:20200712194859p:plain

ここではScalar値を一つだけ登録しました。パラメーター名は time としています。

 

 

Widget用のマテリアルを作る

ベースとなるマテリアルの全体図

f:id:hiyokosabrey:20200712195706p:plain

マテリアルドメイン(右端のノード)は User Interface にします。

普通にカラーテクスチャを使う場合は下のようにつなぎます

f:id:hiyokosabrey:20200712200138p:plain

 

マテリアルパラメータコレクションを利用するには専用のノード

検索で coll と入力すると出てきます

f:id:hiyokosabrey:20200712201356p:plain

f:id:hiyokosabrey:20200712201509p:plain

このノードの設定値として、に用意しておいたマテリアルパラメータコレクションをセットします。

f:id:hiyokosabrey:20200712201811p:plain

プロジェクトが認識しているマテリアルパラメータコレクションがプルダウンから選択できるので、名前を憶えていれば簡単に選択できます。

マテリアルパラメータコレクションを選んだら、ParameterNameも簡単に選べます。

 

 

今回はインスタンス化して汎用的に使いたいのでパラメータはそれなりに用意。

f:id:hiyokosabrey:20200712201119p:plain

 キラキラパターンについては、4色の固定カラーにしたかったのもあって、若干ノードを組み替えてスリムにしたベースマテリアルを用意しています。画像は省きますが、マテリアルパラメータコレクションの使い方は同じ要領です。

 

TilingU と TilingV でテクスチャの切り出す大きさを指定、OffsetV で切り出す位置を指定します。

 

f:id:hiyokosabrey:20200712230042p:plain

値は UVなので、 対象のピクセル数をテクスチャ解像度で割り算します。上図の場合、左上が(0, 0)で、上から64ピクセル下あるパターンだから

 

64÷256 = 0.25  OffsetV は 0.25

 

今回全て左端から並んでいるので、OffsetUは考慮しません。

 

切り出すサイズは 128x128px なのですが、 今回のテクスチャサイズが長方形なので TilingU と TilingV の値は異なります。

 

128÷512 = 0.25  TilingU は 0.25

128÷256 = 0.5 TilingV は 0.5

 

上のベースマテリアルから、マテリアルインスタンスを作って、計算した値をセットするだけで、一枚のテクスチャからいろんなパーツを切り出して、Widgetで利用できます。

マテリアルインスタンスはコンテンツブラウザの対象のベースマテリアルのアイコンで右クリックして作ります。

f:id:hiyokosabrey:20200713223523p:plain

ダブルクリックするとパラメータだけが編集できます。

 

 

Widgetブループリントを作る

あとは表示のための用意としてUMGのキャンバスにImageパーツを配置して、マテリアルインスタンスをセット。

f:id:hiyokosabrey:20200713230138p:plain


新しくアニメーションを追加して、さらにトラックを追加します。

f:id:hiyokosabrey:20200713224027p:plain

プルダウンリストから Material Parameter Collection Track を選択。

f:id:hiyokosabrey:20200713224045p:plain

用意しておいたマテリアルパラメータコレクションを選んだら、今度は変化させるパラメータを追加して、キーを打ちます。

f:id:hiyokosabrey:20200713225523g:plain

パーツごとのアニメーションがあれば合わせて追加しておきます。

 

あとは、このアニメーションを、カスタムイベントで呼び出して再生するようにすれば勝手にアニメーションします。

 

 

f:id:hiyokosabrey:20200713232331g:plain

 

今回のサンプルは目コピーなので、記事にするのはここまでにしておきます。

 

 

マテリアルパラメータコレクションをUMGで制御できるということ

かつて、まだこの方法に気づいていなかった頃、トリッキーな方法でやってました。

 

limesode.hatenablog.com

 無駄にアニメーション用のパーツやプロパティを消費してさらに、EventTick で値を移すという処理を行っていました。

タイムラインを使えば、アナログみのある味わい深いアニメーションを作ることができます。

 

追記: 7/14

この記事を公開したところ、マテリアルパラメータコレクションを使わずとも、直接Imageパーツなどにセットしたマテリアルのパラメータもアニメーショントラックでキーを打つことができるのを教えていただきました。

 

ヒストリアさんとこのブログでも扱っておられました。

イテばし さん情報ありがとうございます。

 

historia.co.jp

実はものすごく欲しかった仕様で、「なんで無いんだろう・・・」で時間が止まってました。いやもう恥ずかしい限りです。ありましたね。

Unity触っててアニメーションキーを打てると分かった時にすごく悔しかった思い出がよみがえりました。でももう大丈夫です。もうUE4さえあれば何もいらないw

 

というわけで、以下の記事を手直します。

<<<

Material Parameter Collection Trackを使えば、EventTickを使わずに済みます。

ひとつ問題があるとすれば、それは Material Parameter Collection の持つ値は『共有』しているということ。シングルトン的なユニークUIであれば、全く気にしなくてもよいのですが、インスタンス化したり、汎用的に扱う場合は注意が必要です。同じパラメータを参照していれば、タイミングが同期してしまうからです。かといってコレクション内にパラメータを増やすのも、メモリの消費が増えるし、だれがいつどの値を書き換えるか管理が必要になってきて、却って面倒な状況になりそうです。

なので、UI表示での使いどころとして提案したいのが

  • ダイアログウィンドウ(モーダルなやつ)
  • 画面フェード
  • ロゴやチャプター名表示、画面見出し
  • 字幕
  • NowLoding

あたりでしょうか。

 

アニメーションでキーを打てるので、もうEventTickを使わずに済みます。

当時は何を思って使えないとなっていたのか今となっては謎ですが、これでもっと凝ったことが気軽にできそうな予感。多分気づけていなかっただけだと思う。悔しい。

 

今回は、マテリアルパラメータコレクションで値を共有しているのを踏まえたアニメーション制御の方法ということで、一例をご紹介させていただきました。

 

ちなみに

今回作ったマテリアルでは、引き算を加えてるので、試しにパーツごとに時間差を作ってみたのが以下

f:id:hiyokosabrey:20200714001923g:plain

 

 

アニメーションパターンを作るのはそれなりに大変だけど、フェードやスケールアニメーションに飽きてきたなーと思い始めたら試してみてはいかがでしょうか。

 

ぜひぜひ

パターンアニメーションでユニークなUI演出ライフを!

 

UMGでのアニメーション終了検出について

 今回の記事はEditorUtilityWidgetを触ってみようとアレコレしているうちに、気が付くとアニメーションの終了検出について調べる流れになったのでそのメモです。

 UIはユーザがゲームと対話するために存在しているので、何かとリアクションするのが重要です。そのリアクションには何かしらの変化(動き)が起きるので、リアクションとして認識させるには、それなりの「間」が必要になります。

 この見た目の挙動を「ふるまい」とか「マイクロインタラクション」などと呼ばれることもあります。

 UIデザイナーが設計して作るリアクションは、細かいパーツの構成を熟知しているUIデザイナーがコントロールできる環境が理想。

 見た目の部分なんで、UIデザイナーに苦情が来やすいのもありますし、アニメーションに関しては表層部分なのでUIデザイナー自身が修正&調整したほうが、プログラマへの負担は減るはずです。

 UIのアニメーションがプログラマ制御だった時代は、いちいち細かい値(12フレームでアルファ0.12ゆうてましけど、やっぱり0.125に変えてもらっていいすか、みたいな)を伝えて修正をお願いしていました。いい時代になったものです。個人的にそんな時代を経験しているので、UE4のUMGがとても素晴らしく映っています。

 

 さてさて、前置きが長くなりました。

 私はUIのアニメーションは大きく2種類に分けられると考えています。

 

  • 終了を待つ必要のない演出やエフェクト的なアニメーション
  • 終了しないと次のフェーズに進まないアニメーション

 

 これはアニメーションの再生と終了のタイミングをどう扱うか、という視点で分類しています。

 前者は、選択中のアイテムがハイライトされている状態や、バックグラウンドで「賑やかし」として動いているようなもの、ローディングなどの待機アニメーション。途中でインタラプトされても問題ないようなシンプルで繰り返す動きのものが多いです。

 後者は、画面のフェードや遷移、決定演出、モーダルウィンドウの開閉演出、など起承転結があり、ゲームの呼吸とかテンポ感に関わる大事な要素です。さらにこの時間はゲームの進行を統括するプログラマにとっては待ち時間となります。

 UIデザイナーがパーツを動かしている間、待ってくれているわけです。こまめに再生中かどうかチェックして終わったら通知、または事前に掛かる時間をタイマー予約するか。という仕組みになると思うのですが、UE4ではアニメーションが終了したことを通知する仕組みをブループリントで用意することになります。その方法をこのブログで何度か書いてきましたが、最近のバージョンでは、その辺りが少し進化しているようなので、自身のアップデートのためにちょっと調べてみました。

 

 その結果、アニメーションの終了を検出する方法を4パターン見つけました。

  追記)Twitterに更新報告をした後に教えてもらった方法も加えて計 6パターンになりました。

 

 

 Get End Time ノードを使う

f:id:hiyokosabrey:20200517173803p:plain

 結構以前から利用させてもらっています。私にとっては馴染み深い方法。

 上の緑色やつが Get End Time ノード。事前にアニメーションの尺を調べておいて、タイマーをセットする方法。アニメーションごとに専用のカスタムイベントが必要になります。ちょっと複雑でノードが多いのが面倒だなと思ってました。

 残念ながら、ポーズ中(4.25で、set Game Paused 使用で試してみました)だと、Set Timer by Eventノードが動かないようなので、ポーズ中ではこのしくみは使えません。Tickは動いているので、自前で時間計測すれば可能ではありますが、この後の方で紹介するイベントを使ったほうが良さそうです。

 

 

Play Animation with Finished Event ノードを使う

f:id:hiyokosabrey:20200517192608p:plain

  4.23で追加された比較的新しめのノード。終了したときの処理をシンプルにつなぐことができるのでノードが少なくてスッキリ。これはいいですね。

 ちなみにこのノードは右上に時計のバッジがついてるので、Delayノード同様に関数では使えません。

 ポーズ中(4.25で、set Game Paused 使用で試してみました)だと、アニメーションは再生されますが、Finishedのピンはポーズ解除後に実行されるので、ポーズ中のUIではこのノードは使えないのが痛い。未来のVerに期待したいところ。

 ブログのコメントでご指摘いただきました。upota さんありがとうございます。

 

 

on Animation Finished イベントを使う

f:id:hiyokosabrey:20200517174050p:plain

 結構古いバージョンから存在は知っていたけど、再生するアニメーションの内容に関係なく終了したらとにかく呼び出されるので、アニメーションを複数抱えたWidgetの場合、対象のアニメーションかどうかの判別や仕分けが必要になったり、Play Animation ノードから離れた場所にこのノードを置くことになるので、若干イベントグラフが読みにくくなる印象があって、なんとなく避けていました。

 

 

Eventキーを利用

f:id:hiyokosabrey:20200517195627p:plain

 タイムラインにイベントトラックを追加して、トリガーとしてキーを打ちます。そこで関数やイベントを呼び出すようにする方法。個人的にUMGのタイムラインの操作方法がやや癖があって難しく感じるのと、操作的なうっかりが起こりやすかったり、呼び出す関数名やイベント名を探してセットするのがちょっと面倒な気がするので普段使わないのですが、好みの分かれるところかもしれません。

 

 

事前にバインドしておく方法

f:id:hiyokosabrey:20200518143826p:plain

K.Y.さんに教えてもらった方法その1

事前に対象のアニメーションオブジェクトに対してバインドしておいて、あとは好きなタイミングで再生するだけ、というタイプ。これなら個別に終了を検出できる。

常駐するWidgetの場合 Unbindのしくみも合わせてコントロールする必要がありそう。

 

 

 

対象のアニメーション専用のイベントを使う

f:id:hiyokosabrey:20200518144333p:plain

K.Y.さんに教えてもらった方法その2

アニメーション名でノード検索すると見つかるやつ。

f:id:hiyokosabrey:20200518144603p:plain

グラフ上でノード検索しないと出てこない代物です。

on Animation Finished イベントはザックリしてますが、これなら確実に対象のアニメーション終了を検出できて、さらにグラフ上でもわかりやすく配置できそうなのはよさそうですね。

 

K.Y.さんありがとうございます!

 

 

 まだこのパターン以外の方法があるかもしれません。Play Animation with Finished Eventノードか、個別の AnimationFinished(xxx) はフロー的にわかりやすくなる感じなので、終了を待ちたい時には積極的に使っていこうと思います。

 ただポーズ中はうまく動かないのがあるので注意。

 こうして挙げてみると選択の幅が広がったので、なるべく可読性とかメンテナンスのしやすさを基準に選んでいきたいなと思うのですが、パフォーマンス的にはどうなのかが気になるところ。引き続き情報のアップデートはしていこうと思います。

 

 アニメーションが終わったことを通知できる仕組みさえ作っておけば、あとからアニメーションのクオリティアップや尺調整は、ずっとUIデザイナーのターンです。自分で責任を持つ範囲が明確になれば、いい仕事ができるはずです。

 確認ダイアログなどで登場演出が終わってないのにキー入力を受け付けてしまったり、フェードアウトしてる途中でバックで絵が変化していたりというカッコ悪いUIにしないためにも、イベントドリブンなUI表示を作れるようにしておきたいものです。

 

ではでは 今回はこの辺で

ステキなイベントドリブンライフを!

 

 

 

 

 

Photoshopで墨流しテクスチャを作る

 連続でネタ投稿というのも自分にとっては面白いチャレンジになっていたので楽しかったでのすが、仕事の準備したり気になってたゲームを始めたりで、結局小ネタツイートは2週間で終了してしまった。ネタ切れなんてとんでもない・・・と思ってはいるのだけど、事前にいくつもネタを思いつくことはないので、常にネタ切れ状態であることもまた事実(汗)・・・お題箱作ろうかな。

 

 さてさて、

 いろいろUIデザインを考えていくとき、ただカタチを置いていくだけだと面白くないので、素材感を乗せてみたりするわけです。最初はネットのフリー素材で試してみて、いい感じになりそうだったら自作します。Photoshopであーだこーだと試行錯誤するわけですが、そこで今回たまたま面白いパターンができたのでメモ程度に記事にしておきます。

 

 元のモチーフは『墨流し』です。マーブリングとも言われたりするやつです。

 美術の時間とかで技法として見かけたことがあるかもしれません。

 技法については以下のエントリーで詳しく知ることができます。

http://nihonga-hobbytimes.com/2018/04/18/%E3%80%8C%E5%A2%A8%E6%B5%81%E3%81%97%E3%80%8D/

 漫画でも混乱中の思考を表現するときなんかに見かけることがあります。

 

 今回は、そんな墨流しをシームレスなパターンとして作成します。

 シームレスだとゲーム画面で容量の節約が出来て便利そうです。

 

 歪みツールはドキュメントの端の処理ができなさそうだったので、仕上げに使うとより効果的だと思います。

 

 まずPhotoshopで新規ドキュメントを作ったら、モノクロで進めるので D キーを押して描画色と背景色を白黒にリセットします。解像度は 1024x1024で作成してしますがタイリングの回数と相談で、いろいろなサイズを作りながら調整することにはなります。

 

フィルタ > 描画 > 雲模様1

 雲模様1は描画色と背景色の2色でランダムな模様を生成します。

f:id:hiyokosabrey:20200513133938j:plain

 

 

フィルター > ノイズ >ノイズを加える

 グレースケールでノイズを掛けます

f:id:hiyokosabrey:20200513134654j:plain

 

 

フィルタ > ピクセレート > 水晶

 うまく黒と白の粒が散らばってくれるといい感じになります。

f:id:hiyokosabrey:20200513134839j:plain

 

 これで基本ができました。かんたん。

 ここからは 渦巻とスクロールを交互に数回繰り返します。

 

フィルタ > 変形 > 渦巻

f:id:hiyokosabrey:20200513135508j:plain

 

 

フィルタ > その他 > スクロール

 シームレスにしたいので、ラップアラウンドを有効にします。

f:id:hiyokosabrey:20200513135725j:plain

f:id:hiyokosabrey:20200513135735j:plain

 適当な距離を見計らってずらします。

 

再び渦巻

f:id:hiyokosabrey:20200513135934j:plain

 

渦巻スクロール渦巻スクロール ・・・・ を何度か繰り返します。

 

 渦巻は毎回向きと量をいじるのをオススメ。

 

 で、できたのがこれ。

f:id:hiyokosabrey:20200513140138j:plain

 

 これをPhotoshopのパターンとして登録してタイリングを確認してみるとこんな感じ。

f:id:hiyokosabrey:20200513140335j:plain

 グラデーションマップで色を変えると・・・

f:id:hiyokosabrey:20200513140956j:plain

 

さっそくこのテクスチャをUE4にインポートして遊んでみました。

ポストプロセスマテリアルを作ってこれをセット。

Lerpでカラーを乗せて、グレーマンのCustomDepthをTrueにして、歪み用のノイズテクスチャでうにょうにょと動かせば出来上がり。

f:id:hiyokosabrey:20200513145718j:plain

このブログは動画をアップできないので、Twitterに貼ります。

動いてるのはそちらをみていただければ。

 

 

 

UMGだと、体力ゲージのデバフ表現だったり、フォントマテリアルとして乗せてみたりしても面白そう。

 

ではでは今回はこのへんで

素敵な墨流しライフを!