【UE4】Instanced Static Meshで部分的に色を変える

f:id:Nasvic:20190408021700g:plain

この記事について

先日第11回UE4ぷちコンへ作品を応募した際、大量に並べたInstancedStaticMeshの特定の箇所のみ色を変えたり、カーソルがオーバーラップしている箇所のみ点滅させたりする方法を模索していたので参考までにその方法を紹介します。



Instanced Static Meshについて

f:id:Nasvic:20190408023608j:plain

今回の作品はキューブを大量に描画する必要があるため、当初キューブは一つずつアクターで処理していましたが、沢山のキューブを描画する場面ではFPSが30以下に落ち込むなど無理があったため、同一のスタティックメッシュを大量に描画することに向いているInstanced Static Meshに置き換えることにしました。

しかし、Instanced Static Meshでは個別にキューブのDynamic material instanceを変更することができず、カーソルとオーバーラップした箇所のみを点滅させたり、Zスケールを変更したキューブのスケール値に応じて色を変えることが通常の方法ではできませんでした。そのため、下記の方法をとりました。


Instanced Static Meshのスケールの値をマテリアル側で読込む

今回ちょうど下記のcom04さんの記事がぴったりで、大変助けられました。マテリアルにカスタムノードを追加して、Instanced Static MeshのZスケール値を読み込んだり、Xスケール値の小数点以下第二位に書き込んだ数値をマテリアルのカスタムノードで読み込み、その数値に応じて点滅させています。
qiita.com


マテリアルでは以下のようにノードを組んでいます

f:id:Nasvic:20190408034010j:plain

左上のカスタムノードAのコードは下記のとおり

(com04さんの記事のコードを改変して利用させていだきました)

#if USE_INSTANCING
/* 行列からスケール値を復元 */
float1 Scale = float1(
length(Parameters.InstanceLocalToWorld[2].xyz));

return Scale;
#else
return -1;
#endif

カスタムノードBのコードは下記のとおり

#if USE_INSTANCING
/* 行列からスケール値を復元 */
float1 Scale = float1(
length(Parameters.InstanceLocalToWorld[0].xyz));

/* 要素を少数第二桁から整数化 */
int3 InstanceIDElements = int1(Scale * 100.0) % 10;

return InstanceIDElements;
#else
return -1;
#endif



Instanced Static Mesh側のBPは下記のとおりです

全景
f:id:Nasvic:20190408033732j:plain

上半分
f:id:Nasvic:20190408142147j:plainf:id:Nasvic:20190408142153j:plain

下半分
f:id:Nasvic:20190408142158j:plainf:id:Nasvic:20190408142141j:plain

Instanced Static Mesh各種Transformの値をマテリアルで取得する方法について、詳細はcom04さんの記事を参考にしていただくとして、点滅の処理はプレイヤーのキャラクターBP(上記BPではキャストしているCursor)の位置を取得し、「Get Instance Overlapping Sphere」の基点としてそこから任意の球径でオーバーラップしているInstanced Static Mesh達を取得し、それらのXスケールの小数点第二位を変更し、マテリアル側の上記カスタムノードBのコードで読み取っています。

また、スケールが変更されたInstanced Static Meshの色の変更も同じように、マテリアル側の上記カスタムノードAでInstanced Static MeshのZスケールの値を読み取ってそれを色の情報に変換しています。


おわりに

f:id:Nasvic:20190408035120j:plain

(上記の画像ではスクショを撮る際にFPSが低下してしまったが、エディタウィンドウでは60FPS以上をキープしている)
以上、Instanced Static Meshで部分的に色を変える方法でした。この方法なら融通が効かないと思っていたInstanced Static Meshでもいろいろできるようになりました。com04さんに感謝…!

UE4のマテリアルやアセット名をまとめてリネームする

この記事について

先日「UE4のマテリアルやアセットをまとめてリネーム(コンテンツブラウザ上でのファイル名の頭に特定の文字列を追加)したいのだけど、なにかいい方法はないか」と聞かれ自分もわからずもやもやしていたのですが、解決したので方法を紹介します

UE4のExperimental(実験的)な機能を使用しているのと、大量のアセットに対して検証していないので問題が起きても責任は負えませんが、参考になれば

 

UE4 Blutilityを使ってのリネーム

基本的には下記(Alweiさんの記事)を参考に簡単なBPを組んだだけです

 

unrealengine.hatenablog.com

 

 

ブログの記事そのままですが、簡単に流れを紹介

f:id:Nasvic:20190129222940j:plain

編集→エディタの環境設定→一般項目の実験段階を選択→Enable Utility Blueprints(Blutility)にチェックを入れて、Blutility(実験的機能)を使用可能にする

 

 f:id:Nasvic:20190129222948j:plain

コンテンツブラウザの新規追加→ブループリント→ブループリントユーティリティ

 

f:id:Nasvic:20190129222932j:plain

親クラスを選択ウィンドウから、GlobalEditorUtillityBaseをクリックし、選択をクリック

 

f:id:Nasvic:20190129223809j:plain

コンテンツブラウザ上に作成されたブループリントユーティリティ(画像ではとりあえずtestと命名しています)を右クリックし、「ブループリントの編集」を選択(ダブルクリックして開くと別の画面が出るので右クリックメニューから開くこと!)

 

f:id:Nasvic:20190129230206j:plain

表示されたブループリント編集画面で、関数の項目から「+関数」をクリックして関数を新たに追加する(下記画像では関数名をRenameと命名しています)

 

f:id:Nasvic:20190129230150j:plain

上記画像のようにブループリントを組む

 

下記のノードを右クリックして検索し、画像のように組む

Get Selected Assets:コンテンツブラウザで選択中のアセットを取得するノード

ForEachloop:繰り返し処理を行うノード

Get object name:オブジェクト名(ここではアセット名)を取得するノード

Append:2つ以上のstring(文字列)を統合するノード

Rename Asset:アセット名を変更するノード

 

組んだらコンパイルをしてウィンドウを一旦閉じ、コンテンツブラウザからいま作業をしていたブループリントユーティリティをダブルクリックして開くか、右クリックして「編集」を選択

f:id:Nasvic:20190129232221j:plain

すると上記のようなウィンドウが開くので、リネームしたいマテリアルやアセットをコンテンツブラウザで選択し、ボタン(画像では関数名をRenameとした)を押す

f:id:Nasvic:20190129232510g:plain

上手くいくと上のGif画像のようにリネームしてくれる

 

UE4 Blutilityを使用した記事ではさらに使いこなして高度な機能が紹介されていますが、ただリネームだけしたいの!という解説は意外と見つからなかったので書いてみました(あったらごめんなさい)参考になれば幸いです