ブループリントでマテリアルやテクスチャを操作する（Unreal Engine 4.25）

# 前提

身内用に書いたものを、暫定的に公開しているものです。何かおこったら閉じるかもしれません。

[前の記事](https://qiita.com/mml/items/5273a7699cdeb9ca21da)に書いた知識（ブループリントの最低限の知識）は持っている、という前提で書いてます。特に説明のない限り、Unreal Engine 4.25 で FirstPerson テンプレートで作成したプロジェクトのレベルブループリントのイベントグラフ上で操作をする前提です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/7689a532-411d-5340-427e-4fc497f9fa06.png)

# 準備

外部オブジェクト(ブループリント）の参照の例の説明のために、FirstPerson プロジェクトにブループリントを追加しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/51aac3d0-b2e5-e60e-b61f-69f6094f41c9.png)

キューブのアクターをひとつ画面内に配置して、右の詳細から「ブループリント/スクリプトを追加」を押して、ブループリントを追加してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/792f09d0-b866-b612-150c-2ce6ca8dd551.png)

デフォルトで Cube_Blueprint という名前のブループリントになりますが、ここではそのままの名前で作成したものとして説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/2a635e11-8f38-48e0-51f7-ee8346539cdc.png)

# ブループリントでマテリアルを操作する準備

アクターの色をブループリントで変えるとか、テクスチャを動的に変更する、みたいなことをするには、アクター（メッシュ）に設定されたマテリアルのパラメータをブループリントで操作する必要があります。

ただし、マテリアルをアプリの実行中に変更はすることはCPUやGPUに大きな負荷をかけるため、基本的にはアプリの実行中にはマテリアルのパラメータを自由に変更できない仕様になっているようです。

ブループリントでマテリアルのパラメータを動的に変更できるようにするには、

1. ベースになるマテリアルを作成する
2. マテリアルの変更したいプロパティをパラメータとして指定する
2. マテリアルをダイナミックインスタンス化する（ダイナミックマテリアルインスタンスの作成）

という三つの操作が（最低限）必要そうです。

## ベースになるマテリアルの作成

ベースのマテリアルは普通に作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/bd235dd7-6e67-b4b3-ee36-3de0b75458ad.png)

コンテンツブラウザで右クリックして、マテリアルを選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/5c051fad-4fe9-c046-641f-67b07444d7cb.png)

作成したら名前をつけておきます。ここでは LchikaMaterial としました。以下、この名前にしたものとして説明します。

## 変更したいマテリアルのプロパティのパラメータ化

パラメータの指定というのは、パラメータに名前を付けるくらいの意味です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/ed3117b1-1c05-5f70-1bc7-16d25accb361.png)

作成した LchikaMaterial  をダブルクリックして開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/fa17d86d-343e-76fa-8f34-c9556ffc5ae5.png)


例えば、ベースカラーをブループリントで操作したい場合は、ベースカラーのところで右クリックして「パラメータへ昇格」を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/ca0e312e-821b-0477-1dd2-4e1510214fe4.png)


すると、こんな感じで「ベースカラー」というノードができます。通常のマテリアルなら、ベースカラーのノードで色を設定したりしますが、パラメータ化が目的なら色の設定をする必要は特にありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/50d37413-6b10-77ba-988b-00a1b88fc656.png)

追加されたノードの Parameter Name を変更しておきます。この Parameter Name は ブループリントでプログラムを書くときに使うので、わかりやすい名前にしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/6a9b03c8-ce9f-b355-5e0e-75898c61df84.png)

ここでは CubeColor という名前にしました。以後、この名前にしたものとして説明します。

## マテリアルをダイナミックインスタンス化する

この操作はエディタではできず、作成するためのコードを書く必要があるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/fbeeb08a-51cd-81ee-4d9b-2339d7e9f99d.png)

Create Dynamic Material Instance ノードを使うことで、ダイナミックマテリアルインスタンスを作成することができます。上の例では Construction Script に書いています。ここに書いておけば、ビルドした時点で LchikaMaterial を親（ベース）のマテリアルとしてダイナミックマテリアルインスタンスが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/c2157785-60fa-b1dc-4702-9ee23832c17f.png)

作成するだけならこれだけでOKですが、メッシュの色を変えるためにこのインスタンスを使うためには、メッシュのマテリアルとして設定する必要があります。

上のコードの SetMaterial のノードで、作成したインスタンスを Cube_Blueprint のマテリアルとして設定しています。最後の SetVectorParameter ノードでは、マテリアルのベースカラーを赤っぽい色に設定しいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/e0cf94dd-83c7-3bc4-bb65-0aed33bd315a.png)

Construction Script にコードを書いているので、これらをビルドした時点でエディタ上の Cube_Blueprint の色が赤になるはずです。もし変化しないとしたら、ここまでの操作のどこかが間違っています。ParameterName や OptinalName をタイプミスしている可能性が高いです。

ここでのポイントは、最後の SetVectorParameter ノードで Parameter Name に、最初に作ったマテリアル（LchikaMaterial）でパラメータ化した CubeColor を指定しているところです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/6a9b03c8-ce9f-b355-5e0e-75898c61df84.png)

CubeColor を指定することで、先にパラメータ化したベースカラーの色を変更することができます。

# ブループリントでマテリアルを操作する

## マテリアルの色を変える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/c2157785-60fa-b1dc-4702-9ee23832c17f.png)

作成したダイナミックマテリアルインスタンスを CubeMaterial という変数にいれているので、あとはこの変数を使って SetVectorParameter などのノードを使えば、プログラム中で色を動的に変更することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/479fb7e8-a899-a118-1409-0ee5e692af35.png)

たとえばこんな感じのコードを Cube_Blueprint に書けば、球やプレイヤーがキューブにぶつかると色が変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/0ed1da7d-3c5d-508b-d680-052a3a59e437.png)

アプリ起動時はこの状態です。マウスの左ボタンで球を撃ってキューブにあてると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/45ef0c86-a14c-d122-36c0-567a5ee1de80.png)

色が青くなります。よね？

## テクスチャを変える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/53d83e69-4fa3-4c85-efae-11c11455d6cb.png)

ベクトルではいスカラー値のパラメータは SetScalerParameterValue ノードを、テクスチャ関連は SetTextureParameterValue ノードで指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/fe3a1084-a944-204d-4ebd-c535f784d67a.png)

テクスチャのパラメータは TextureSampleParameter2D などが使えるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/62c5f1b7-5e55-792f-45ff-5d9c6ade5221.png)

上のようなコードで、テクスチャを変更できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/2ecf0ff3-bd4d-2644-94e1-83cbbd7df768.png)

初期化はこんな感じでいけるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/45770f1a-56f8-4c3a-c8f7-9e810e5614e3.png)

これでキューブを撃てば、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266247/6e86693a-5031-c38f-c389-f3dba2dfec34.png)

テクスチャが変更されます。

このくらいヒントがあれば（以下略

# 今度こそ終わり