みつまめ杏仁

アンリアルエンジン(UE4)でGUIを作るためにゴニョゴニョしてます。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さんありがとう!

 

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

 

 ではでは今回はこの辺で

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

UE4でパーセント表記

戦績などのスコアを表示するリザルト画面や、武器やキャラのステータス表示で、「命中率」や「回避率」など「○○率」を表記することがよくあります。

この「○○率」を表示してやんよ~というわけで気軽にやってみたのですが、なかなかうまくいきませんでした。ははは。

 

例えば、命中率の計算。必要な情報は 『撃った弾数』と『当たった数』です。

基本的に『当たった数』を『撃った弾数』で割ればよいだけです。

100発100中なら100%と書けばいいのですが、300発100中ならどうなるでしょう。

 

100 ÷ 300 で 0.33333333333333333333333333・・・・

 

このように割り切れない場合があります。これを、33.33% と書きたいわけですよ。で、どうするか? 昔JavaScriptで覚えた方法を試します。

小数点以下2桁にしたい場合。

100 + 2桁のゼロ で 10000  まずは この 10000 を掛けてやります。

f:id:hiyokosabrey:20161123232534p:plain

ゼロが4つで、小数点が4つ移動します。上の場合 5898.7654

掛けた値を四捨五入します。四捨五入した時点で小数点以下は消えるので、整数になります。この時点で、4桁の整数になっています。 上の場合 5899

それをさらに 100 で割ります。小数点が右端から2つ移動します。

f:id:hiyokosabrey:20161123232833p:plain

PrintStringノードで表示してみます。

58.99 が表示されればバッチリです。

f:id:hiyokosabrey:20161123233418p:plain

な、なんじゃぁこりゃぁ。2はどこから?

ネットで調べてみると、どうもイロイロ事情があって仕方のないものらしい。

コンピュータは基本 0 と 1 の2進数で動いていて、この2進数で小数点を表すことが苦手なようで、上のような微妙な誤差が生まれるとのこと。お金の計算でこの誤差はヤバいのでさすがにちゃんと対策されているそうです。なるほど小数点を扱うのは結構難しいもんですね。ふふふ。

いやいや。表示しなきゃいけないのですよ。

で、思いついたのが、四捨五入した時の Int型の値を、String型(文字列)にして分割してしまう方法。

f:id:hiyokosabrey:20161123235510p:plain

整数同士の割り算は小数点以下を切り捨ててくれます。 上の場合  5899 ÷ 100 で 58。

f:id:hiyokosabrey:20161123235758p:plain

うまくいきました。

ただこの方法だと、 必ず小数以下の2桁分がくっつけられるので、割り切れたとしても最後に0が付きます。

0.5 の場合、0.5 × 10000 = 5000 になるので、 50.00% と表示することになります。

 

なんか面倒な感じがして釈然としないので、便利そうなノードが用意されてたりしないかな、ゲームエンジンなんだし・・・と思いつつ探してみたらありました。

AsPercent ノード。

f:id:hiyokosabrey:20161124000924p:plain

Epicありがとう!

Float型の値をパーセント表記に、しかもテキストで返してくれるというすぐれもの。

f:id:hiyokosabrey:20161124001330p:plain

Text型ということは、UMGのTextBlock でサクッとと表示できて便利です。結果は、

f:id:hiyokosabrey:20161124001531p:plain

おお!カンペキ! もっと早くに出会っていれば・・・(涙

右端の桁に 0 もつかないというシンプルさ。

f:id:hiyokosabrey:20161124001833p:plain

ちなみに、小数点以下を固定の桁で四捨五入するのを「丸める」といいます。

AsPercent ノードの設定で好きな桁で丸めることができます。

f:id:hiyokosabrey:20161124002806p:plain

Rounding Mode は丸める方法です。

詳しくはWikipediaで。(端数処理

 

ということで無事解決しました。

プログラマにテキストで頂戴って言えば、きっといい感じの関数を書いてくれそうですが、やっぱり表示する部分はUIデザイナーでも頑張ってみたいところです。

 

ではでは

今回はこの辺で

 

 

 

 

 

 

 

 

 

 

A と B を交互に切り替える処理でハマった話

TVのリモコンを握っている状況をイメージしてください。

TVが点いていない状態で電源ボタンを押すと起動して、点いている状態で押すと待機モードになります。

どちらの操作も同じボタンを押すことで切り替わります。

このように、A と B の2つの状態があって、一つの関数を呼ぶだけでスイッチングできないかなと思って試してみました。

 

実行するたびに、2つの処理を交互に切り替えたいので、引数で切り替えるのは無しです。

f:id:hiyokosabrey:20161119231759p:plain

ようするに関数を単純に呼び出す(Call)だけでスイッチングしたいのです。

呼び出す側は「関数の中身なんか知ったこっちゃねぇ。」という状況が理想。

さらにシンプルなノードでできると尚良し。でやってみたのがこれ。

f:id:hiyokosabrey:20161119232657p:plain

XOR ノード は 「排他的論理和」というやつで、同じものが来たら反転するというひねくれものです。違うもの同士は足します。↑の場合チェックボックスにチェックが付いている状態なので、

f:id:hiyokosabrey:20161119233741p:plain

結果をすぐに変数にセットしてるので、内容が反転したことになります。

f:id:hiyokosabrey:20161119234253p:plain

 

できれば変数を使わない方法でシンプルにできないかと思ってやってみたのがこれ。

f:id:hiyokosabrey:20161119234611p:plain

結果はというと・・・

f:id:hiyokosabrey:20161119234644p:plain

ここでようやくハマった話。

 

この MultiGate ノードを使ったつなぎ方は一度経験していて、当時はうまくいってました。で今回は「なんで?」となったのです。

結論を言ってしまうと、MultiGateノードは関数内に置くときは取り扱い注意 です。

単に「ランダムな結果を返せ」だったら is Random にチェックを付ければ問題ないです。今回のように上から実行ピン(Out 0 → Out 1 → Out 2 ・・・)を順番に流す場合はうまく働いてくれないことが分かりました。

関数の外に置いてみるとうまく働いてくれます。

f:id:hiyokosabrey:20161119235946p:plain

Epicの公式ドキュメントにそれらしい記述が見つけられなかったので、当たり前の仕様なのか、バグなのかはプログラマじゃないのでなんとも言えないですが、ちょっと謎です。

 

もっとシンプルに切り替えるノードを思い出しました。FlipFlop ノードです。

「MultiGateはそういう仕様なんだ、でもFlipFlopなら状況を打開できるかも・・・」

と淡い期待を抱きつつ・・・

f:id:hiyokosabrey:20161120000725p:plain

こちらも関数内に置いて使うと、Aのピンしか流れません。

外に出してみるとうまく動きます。

 

結局、外部から呼び出してスイッチングしたかったので、カスタムイベントにつなぐことで解決しました。

f:id:hiyokosabrey:20161120001714p:plain

これでバッチリです。

ちなみにマクロの中で使う分には問題なく動作します。

ですが、そのマクロを関数の中に置くと、切り替わらないという結果になります。

 

あくまでも推測ですが、

切り替えるには、状態を保持しておく値が必要で、関数内からはその値が参照できなくなるんじゃないかと思ってみたり。

 

 

ではでは

今回はこの辺で。

ステキなノーディングライフを!

 

 

 

 

5分で作る マテリアルを使わないゲージ

超簡単お手軽ゲージを作ってみます。マテリアルは使いません。

Widgetブループリントを一つ用意します。

キャンバスに配置するパーツは3つ。

f:id:hiyokosabrey:20161114000006p:plain

ゲージ用のキャンバスとゲージの下敷きは同じ大きさにします。下敷きは暗めの色にしておきます。

ゲージ本体の「Image」をキャンバスの子供にしたら、設定をサクッと変更します。

まずはAnchors(アンカー)を右下のやつに変えたら、

f:id:hiyokosabrey:20161114000321p:plain

すぐ下にあるOffset関連の値をすべて0.0にします。

f:id:hiyokosabrey:20161114000622p:plain

カラーを適当な色にしたら、

f:id:hiyokosabrey:20161114001020p:plain

 

最後にキャンバスパネルの  isVariable のチェックを入れて完成です。

f:id:hiyokosabrey:20161114001028p:plain

 

編集モードをグラフに切り替えて、MyBlueprint のタブから、Function(関数)をひとつ追加します。

中身は以下。

f:id:hiyokosabrey:20161114001531p:plain

コンパイルしてエラーがなければ保存して完成です。

 

レベルから確認してみます。

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

f:id:hiyokosabrey:20161114002256p:plain

再生してみると、

f:id:hiyokosabrey:20161114002507p:plain

f:id:hiyokosabrey:20161114002512p:plain

f:id:hiyokosabrey:20161114002518p:plain

スペースキーを押すたびに長さが変化します。

 

完成です。

実際に時計見ながら作ってみたのですが、5分かからなかったです。

 

見た目には安いですが、このスピード感は大事です。

ゲージ一本でゲーム性やバランスが大きく変わるのはよくある話です。

 

ではでは

ステキなゲージライフを!

 

 

 

最近ハマったつなぎ方

ちょっとネタが無くなってきたのもあって更新ペースが落ちてます。

なので自分のウッカリでもさらしてみようかなと。

 

それは思ったような値にならず、原因も分からず、しばらく首をひねっていたつなぎ方です。

 

まずUMGでパーツを置いて、Widgetブループリントからいい感じにサイズを計算して調整しようとしました。

下図は 160x256 サイズの”Image”です。

f:id:hiyokosabrey:20161105010212p:plain

これを、下のようにつなぎました。

計算した値を別のところで使いたかったので変数に保存しています。

f:id:hiyokosabrey:20161105010316p:plain

ここで察しのいい方は気づかれていると思います。

Imageパーツのサイズをゲットして、タテ方向だけ1/16 にしてサイズを変更しています。

果たして、変数 Value の値はどうなっているでしょうか?

再生すると、パーツの見た目には うまくいっているように見えます。

でも、

答えは、 Value = 1.0  です。

 

え?

だって 256を16で割ったら16でしょ? なんで???

 

実際には 256 ÷ 16 = 16  したあとで、さらに 16 ÷ 16 = 1  となっているからです。

なんと割り算が2回計算されているのです。

 

SetSizeノードに割り算の結果が渡されたあとで、次は変数に値を渡すためにもう一度Imageパーツのサイズを取得して(このとき既に16になっている)16で割っています。
 

 見た目に、割り算ノードのあたりで計算が済んでいるように見えるのと、同じピンから取り出してるので、同じ値が出てくると思ってしまったのが原因でした。

 

正しくは以下。

f:id:hiyokosabrey:20161105044358p:plain

 

変数に値を入れない場合でも、値を確認しようとしてPrintStringノードをつなぐと・・・

f:id:hiyokosabrey:20161105045402p:plain

 1.0 という数値が表示されます。

PrintStringノードが値を表示しようとして、2回目の計算を行ってしまうためです。

 

では以下の場合はどうでしょう。

f:id:hiyokosabrey:20161105050009p:plain

 無事 16.0 という数値が表示されます。Imageパーツはというと問題なく 1.0 にならずに表示されています。

おそらくこれも2回計算していますが、PrintStringノードは、SetSizeノードのように結果を反映しないので、問題が起こらないのです。

 

この辺りのロジックが理解できるまでしばらくの間、首をかしげっぱなしでした。

 

以前に 乱数を発生させるノードでも同じようにハマったのを思い出しました。

例えば下のようにつないだ場合、

f:id:hiyokosabrey:20161105051632p:plain

画面には、2つの異なる数値が表示されます。

 

以後気をつけます。

 

ではでは

ステキなノーディングライフを!

スタッフロールをつくる 《完結編》

鶏肉は柔らかいのより噛みごたえのある方が好きです。

で前回の続き。

limesode.hatenablog.com

名前を表示するための器が用意できたところで、次に必要なのは中身です。

スタッフロールには関わった多くの人々の名前が載るので結構な行数になることが多く、それをブループリントの中で管理するのはさすがにちょっと躊躇われます。また、スタッフロール用の情報を集めて整理するのはExcelやテキスト系エディタの方が向いています。

というわけで今回CSV形式のデータを扱います。詳しくはヒストリアさんとこのブログにあります。

[UE4] CSVデータを扱う方法 DataTable編 | historia Inc - 株式会社ヒストリア

CSVは『カンマせぱれいてっどバリュー』の頭文字を合わせた用語で、簡単に言うと「カンマで区切った値」ということになります。Excelだと簡単に書き出せるのですが、Excelを持ってないのでテキストエディタで作りました。

f:id:hiyokosabrey:20161022231932p:plain

いくつかのデータをカンマで区切るのですが、今回4つのデータで構成します。

 

Index番号    表示タイプ     名称(文字列)   次の行までの待機時間(秒)

 

用意したWidgetは3タイプ。表示タイプを『グループ』『パート名』『人名』を0~2の数値で扱うことにします。で、できたのが以下

,NameType,NameString,NextInterval
0,0,STAFF,2.0
1,1,ROSE,1.0
2,2,Abigaile,1.0
3,2,Acropolis Romantica,1.0
4,2,<>Alphonse Dauder<>Anthony Meilland,1.0
5,2,<>Bienvenue<>Benjamin Britten,1.0
6,2,<>Cassandra<>Cioccofiore,1.0
7,2,<>Dorothy Perkins<>Gloria Mundi,3.0
8,1,DAHLIA,1.0
9,2,Anto Norma,1.0
10,2,<><><>Azumabeni<>Ben Houston<>Blookside Snowball,1.0
11,2,<><><>Devon Liam<>Freedom Fighter<>Gregory Stephenl,1.0
12,2,<><><>Happy Face<>Hoshitsukiyo<>Lavender Giantsl,3.0
13,1,TULIP,1.0
14,2,<>Dalvey Snow<>Cardinal Mindszenty,1.0
15,2,<>Finola<>Flaming Prissima ,1.0
16,2,<>Honoonomai<>Lambada,1.0
17,2,<>Maywonder<>Murasaki suisho,1.5
18,2,Page Polka,1.5
19,2,Ruby Prince,3.0

プレーンテキストなので Tab文字 を入れれば見やすくなりますが、文字として扱われてしまうのでCSVとして書き出す直前に置換して消すといいです。

文中の <> は分割するためのデリミタ用の文字です。

この内容で、拡張子 .csv を付けて保存するとUE4でインポートできます。

インポートする前に用意するアセットがあります。Structureです。

f:id:hiyokosabrey:20161023110627p:plain

ストラクチャーを作ったら適当に名前を付けて編集を開始します。編集と言っても変数を登録しておくだけのものです。

f:id:hiyokosabrey:20161023111454p:plain

表示タイプ(Int型) , 名称(String型) , 次までの待機時間(Float型)なので3つ。

4つのデータを仕込んだはずですが、今回 Index番号については特殊な扱いをするので変数にはしません。

追加したら保存して閉じます。

 

いよいよインポートします。作ったCSVファイルをコンテンツブラウザにドロップすると下のような小さなダイアログが出てくるので、先に作っておいたStructureをプルダウンリストからアセット名で選択します。

f:id:hiyokosabrey:20161023113903p:plain

OKするとDataTableアセットのエディタが開きます。

f:id:hiyokosabrey:20161023114218p:plain

問題なければ左上のFile メニューから 保存 して閉じます。

 

このエディタからも内容の編集が可能ですが、スタッフロールについてはReimportをオススメします。名前の収集がメールベースというケースがほとんどで、最後までExcel等で管理した方が修正も楽ちんでお手軽です。

Reimportは、コンテンツブラウザのアセットアイコンの上で右クリックすると簡単にできます。

f:id:hiyokosabrey:20161023115453p:plain

 

器と中身が揃ったので、表示する処理を作っていきます。

ブループリントアクターを使ってWidgetを表示します。

 

まずは、変数を2つ作って、Event Begin Play のところででセットします。

f:id:hiyokosabrey:20161023142246p:plain

 中央の見慣れない色の変数は、 UserWidget型の変数です。作る際にClass を選択するのがポイントです。

 f:id:hiyokosabrey:20161023142703p:plain

Make Array ノードをつないで、用意してある3タイプのWidgetアセットをセットします。

 

次に、メインとなるカスタムイベントを作ってつないでいきます。

まず最初に、DataTableアセットを取り込みます。

f:id:hiyokosabrey:20161023194843p:plain

DataTableを取り込むノードは2つ用意されているようで、getdata で検索します。

f:id:hiyokosabrey:20161023195217p:plain

Get Data Table Row ノードは Indexの値をName型に変換して、RowNameピンにつなぐとヒットすれば、その内容を取り出すことができるノードです。青いピンにまとめられているので、Breakeノードで分解すると変数ごとに振り分けられたピンが出てきます。それを使ってどんどんつないでいきます。

f:id:hiyokosabrey:20161023200056p:plain

図の Wd Credit Text (実際は wd_CreditText)という名前の変数は Create Widgetノードの 右にあるReturnValueピンから、一度 Promote to Variable(変数化)してから配列化したものです。今回インターフェイスを使ったしくみが活かされている部分がここです。

左の Create Widget ノードにはまだどのWidgetが入るか確定していません。確定していない証拠に ReturnValueピンから作った Wd Credit Text の型は User Widget型のままです。普通ならClassの部分にセットしたWidgetアセットの型になるはずです。そしてその型が確定しているからこそ中の関数やイベントを呼び出せるのです。ところが確定していないのに中に作ったイベント StartMove を呼び出すことができています。これがインターフェイスという仕組みなのです。StartMove ノードの右上に 封筒のアイコンがついてます。ノードを取り出す際に ”start” で検索すると取りだすことができます。

f:id:hiyokosabrey:20161023220838p:plain

インターフェイスを持っている相手なら、誰であるか特定できていなくても、そのインターフェイス経由で関数やイベントを呼び出すことができるのです。

おかげでノードのつながりがシンプルになります。

 

では続きを。

Widget仕込んだイベントディスパッチャーにバインドしています。これは「移動が終わったら連絡ちょうだいね」という部分で、連絡を受け取ったあとの処理を下の赤いラインの先で行っています。

f:id:hiyokosabrey:20161023221702p:plain

バインドインターフェイスの仕組みでできれば、スイッチノードで分けたりキャストしなくて済んだのですが、残念ながら無理でした。Set Timer by Event ノードは指定した時間がきたらEventピンにつないだイベントを呼び出すノードです。で、どこにつなぐかというと、先頭です。

f:id:hiyokosabrey:20161023222532p:plain

これで、Forloop などのノードを使わずに、イベントがイベントの終わりで自分自身を呼び出すカタチになります。このイベントが呼ばれると

  1. データテーブルから1行分のデータ取り出す
  2. 指定のあった名前表示用のWidgetを生成して配列に積む
  3. Viewportに追加してStartMoveイベントを呼ぶ。このとき名前のテキストを渡す。
  4. 移動完了の連絡を受け取るためにバインド
  5. データテーブルの指定通りにタイマーをセット
  6. Index変数を一つすすめておく

という流れで処理されます。

で、移動完了の連絡を受けたら、もうそのWidgetは用済みなので、メモリ節約のために削除してやります。

f:id:hiyokosabrey:20161023223954p:plain

先にViewportの方から削除します。スタッフロールは下から順番に出てきて順番に消えていくものなので、配列に積んだ一番古いやつ=先頭から消すことで新陳代謝できます。

ほぼ完成なのですが、このイベントを呼び出さないとイベントは動きません。

そこで Event Begin Play の最後につないでやります。

f:id:hiyokosabrey:20161023224549p:plain

 

ところで、このループはいつ抜け出るのか?という心配をされている方、ご安心ください。Get Data Table Row ノードが解決してくれます。

f:id:hiyokosabrey:20161023224919p:plain

Index という変数が肝だったのです。Name型にキャストして検索。見つかれば Row Found、見つからなければRow Not Found に流れます。これで、データテーブルから該当するナンバーが無くなったらこのイベントのループは終了します。

 

今回も長い道のりでした。

ようやくこの作業が報われる瞬間がやってきました。

では表示してみましょう。

空っぽのレベルを開いて、作ったこのブループリントをエディタのViewportにドロップします。場所は適当で構いません。そのままPLAYボタン押せばOK。

f:id:hiyokosabrey:20161023230020p:plain

・・・

なんかしみじみ。

自分の名前を入れてみるとより感動するかもしれません。

 

内容が変わったときは、リストを編集して再インポートすればすぐに確認できます。

新しいWidgetを追加する場合は、まず↓

f:id:hiyokosabrey:20161023230459p:plain

そして

f:id:hiyokosabrey:20161023230727p:plain

あとは、CSVデータの方に追加した表示タイプを入れればOK。

ロゴもWidgetを複製して改造すれば同じ方法でどんどん追加できます。

 

以上です

ではでは、ステキなスタッフロールライフを!

スタッフロールをつくる 《Widget準備編》

画面の下から出てきて上に消えていくだけの、どシンプルなスタッフロールを作ってみました。

f:id:hiyokosabrey:20161021233614p:plain

今回用意するアセットは以下の6種類8個。

f:id:hiyokosabrey:20161021233902p:plain

右のWidgetブループリント3つはほとんど同じ内容。

 

スタッフロールは、ただ名前が並んでるだけではなく、組織やグループ、セクション、パートなどの名称、協力会社さんのロゴ、俳優さんや声優さんなどは役名と対で表示したりと、結構表記のバリエーションを用意する必要があります。

今回は『グループ名』、『パート名』、『人名』の3種を作ります。

人名に関しては、1列~3列まで対応します。

 

まずは見た目の材料ということで、グループ名のWidgetから。

キャンバスの適当な場所にテキストブロックを一つだけ置きます。

f:id:hiyokosabrey:20161022000037p:plain

文字サイズは 少し大き目にして他と差をつけるために色を付けます。

f:id:hiyokosabrey:20161022000503p:plain

位置を調整する前に アンカー の設定を変更します。

f:id:hiyokosabrey:20161022000917p:plain

決定するとキャンバスの表示が変わります。

f:id:hiyokosabrey:20161022001352p:plain

次にSlotの中にある Anchors のパラメータを変更します。

f:id:hiyokosabrey:20161022001749p:plain

SizeY以外0.0 にすると下のようになります。Position Y を動かすと移動できます。

f:id:hiyokosabrey:20161022002112p:plain

最後に Is Variable にチェックを付けて、UMG編集完了です。

f:id:hiyokosabrey:20161022002605p:plain

 

次に

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

スクロールに必要なFloat型の変数3つ用意します。

f:id:hiyokosabrey:20161022003300p:plain

キャンバスに置いたTextBlockをグラフにドラッグ&ドロップしたら、Event Constructノードにつないでいきます。

f:id:hiyokosabrey:20161022004308p:plain

UMGで配置したものをブループリントから触る場合、Slot as Canvas Slot ノードを利用します。上のグラフは、画面下から出現して画面上に消えるまでの移動量を求めて変数に入れています。とりあえずフルHDモニタ想定で以下のイメージになります。

f:id:hiyokosabrey:20161022010533p:plain

今回選んだアンカーの設定にある PositionY は、0.0でスタートして最終位置は マイナスの値になります。そこで -1080 から サイズ(高さ)を引くことで、最終位置を求めることができます。720pだったら、 -720 から引いてやります。解像度に対して柔軟に対応する場合は、Get Viewport Size ノードがあるので、その値を利用するとさらに汎用性が上がります。

最終位置を求めるのにわざわざGet Sizeノードを使わなくても、動かしてみれば簡単に最終位置は判明します。これは、あとからサイズを調整する際、変数の値を変更しなくてもいいというのとマジックナンバーを使わなくていいというメリットがあるためです。気軽に感覚的にサイズを調整することができます。こういうちょっとした処理を仕込んでおくだけで調整の手数を減らすこともできるのでオススメです。

 

次に

移動が終了したことを伝えるためにイベントディスパッチャーを用意します。

f:id:hiyokosabrey:20161022090456p:plain

追加ボタンをクリックして名前を付けるだけでOK。

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

 

移動させる部分を作っていきます。

f:id:hiyokosabrey:20161022092617p:plain

Event Tick ノードにつないでいきます。

In Delta Time ピンからは フレーム毎に下図のような数値が流れてきます。

f:id:hiyokosabrey:20161022094432p:plain

フレームというのは映画でいえばフィルムの1コマにあたります。

これは 60fpsの場合ですが 1秒を 60で割った値とほぼ同じで、直前のフレームからの経過時間を表しているそうです。若干のバラツキはありますが、ここに60 を掛けてやれば、1フレームあたり 約1という値になります。なので 変数Speedに60が入っていた場合、1フレームにつき1ピクセル進むことになります。120が入ると2ピクセルになるのでスピードが上がります。

1フレームに進む移動量をY座標に足して、限界を超えたかどうかチェックします。

越えていなければY座標をテキストブロックに反映して次のフレームへ。

越えたらイベントディスパッチャーを呼び出します。

イベントディスパッチャーは ドラッグ&ドロップしてCallを選択したものです。

 

一旦ここで編集を終了して、ブループリントインターフェイスを作ります。

f:id:hiyokosabrey:20161022103631p:plain

適当に名前をつけて開いたら、右上に New Function_0 という関数があらかじめ置いてあるので名前を変更します。とりあえず StartMove と命名しました。

f:id:hiyokosabrey:20161022104211p:plain

続けて、下のDetailsタブから、Inputs(引数)を2つ追加します。

f:id:hiyokosabrey:20161022104203p:plain

これでブループリントインターフェイスは完成です。コンパイル→保存して閉じます。

 

さきほどのWidgetの編集を再開します。

編集モードをグラフにすると、エディタ上部にClassSettings というボタンがあるのでクリックしてDetailsタブの内容を切り替えます。

f:id:hiyokosabrey:20161022104816p:plain

DetailsタブにInterfaceを登録する場所があるので、Addボタンをクリックしてさっき用意したブループリントインターフェイスをセットします。

f:id:hiyokosabrey:20161022105340p:plain

追加できたら、グラフの何もな無いとこで右クリックして

 ブループリントインターフェイス内に作った関数を探します。

f:id:hiyokosabrey:20161022110526p:plain

 

関数名の頭にEvent がついている方を選ぶと以下のようなノードが出てきます。

f:id:hiyokosabrey:20161022110712p:plain

 右上にインターフェイスのアイコンがついています。

ここに最後の仕上げ。

f:id:hiyokosabrey:20161022111904p:plain

これでWidgetブループリントは完成です。

 

コンテンツブラウザからこのWidgetを2つ複製します。

複製した1つ目を開いてテキストブロックの見た目を変更します。

パート名用です。

f:id:hiyokosabrey:20161022112559p:plain

文字サイズを少し小さくして、カラーを変えています。

これで2つ目完成。

 

最期の3つ目は人名用。複製した残りのWidgetブループリントを改造します。

文字サイズとカラーを変更するのですが、ここで複数列の対応を追加します。

 

まずは編集モードをDesignに切り替えてキャンバスパネルを追加します。

その中に6つのTextBlockを入れて子供にします。

f:id:hiyokosabrey:20161022200151p:plain

アンカーの設定はそれぞれ以下のように変更します。

f:id:hiyokosabrey:20161022201434p:plain

レイアウトは下のような並びで配置しますが、

f:id:hiyokosabrey:20161022195833p:plain

実際には1行に重なった状態にします。

f:id:hiyokosabrey:20161022201649p:plain

テキストブロックの中は何も文字を入れないように空にします。

f:id:hiyokosabrey:20161022202229p:plain

あとはカラーと文字サイズ、字詰め方向(Justify)を設定したら、Is Variable にチェックを付けて編集モードをグラフに切り替えます。

 

String型と、TextBlock型の配列変数を用意します。

f:id:hiyokosabrey:20161022202800p:plain

TextBlock型は、Object Typesの中にあります。

f:id:hiyokosabrey:20161022202825p:plain

f:id:hiyokosabrey:20161022203044p:plain

6つのテキストブロックを配列に積みます。

移動するのは、キャンバスパネルになるので Slot as Canvas Slot ノードには、追加したCanvasPanelをつなぎます。

f:id:hiyokosabrey:20161022203413p:plain

インターフェイスで仕込んだ StartMove関数(ここではEvent)の部分を以下のように改造します。

f:id:hiyokosabrey:20161022204820p:plain

Parse Into Array ノードは指定した文字列(デリミタ)が見つかると分割して配列にしてくれます。

人名のWidgetはこれで改造完了です。

これですべてのWidgetブループリントが完成しました。

 

今回はこの辺にしておきます。

次回はデータの準備と表示する部分を書きます。

ではでは