Unity用マテリアルチェンジャーを作りました
- BTA(Kelorin Jo)
- 2020年1月13日
- 読了時間: 3分
シーンに配置したモデルの任意のマテリアルを
プリセットから選んでランダムに置換するスクリプトを作りました

結構苦しんだので、これは配布するか有料にするか考え中です
おそらく他の役立ちツールができたらセットで販売、頓挫したら無料配布て感じの予定です。
最初に、エディタ拡張でなく実行時に動作する版作ったけど

いじっててなんかおかしいぞってなって調べたところ、
Unityでは実行時のマテリアルって
オブジェクト(インスタンス)ごとに別々に複製されてたのですね。
プレハブに使われてたマテリアル数×シーンに配置されてるオブジェクト数という
べらぼうな数のマテリアルが作られた
それをこのスクリプトで更に差し替えると、差し替えた分だけ増えてた…
差し替える前にマテリアルを参照するだけ、GetComponent<Renderer>().Materialにアクセスするだけでも強制的に増えるんだとか。
(どれだけ増えるかは、上メニュー/Window/プロファイルから確認できます)

しかも差し替える前の元マテリアルは自動で破棄されず、メモリに残り続けるだって
未使用マテリアルを破棄するのはインスタンスごとメモリから消すなら簡単だけど、未使用分だけ消すのは難しいみたい
オープンワールドに自動生成した建物やモブへの使用を想定して作ったので、むちゃくちゃ大量のゴミマテリアルを作ってしまいそうじゃないの。
自動生成せざるを得ない状況でないなら、できる限り実行前に建物並べてマテリアル差し替えるほうが安全そうということで、エディタ拡張を作りました。
ただエディタ拡張は、アンドゥが完璧には効かないという悩みがあります。アンドゥ機能は効くときはあっさり効くけど効かないときは頑として効かない代物なので…
ちなみに同時に、窓のマテリアルのエミッションを昼夜で変えられるスクリプトも作ってましたが、これもばっちりマテリアルが増えます。

複製されたマテリアルに対して作用してるので、
スライダーいじって窓の色が変わるのはスクリプトをアタッチした1オブジェクトだけです。
シーンにある大量のビル窓やネオン照明をすべて個別に操作しないといけない、
実行時にプロジェクトにある元のマテリアル(SharedMaterial)の方をいくらいじ
っても、すでに生成されたインスタンスには反映されませんでした。
これは使いづらい…
いや、シーン上にある窓付きオブジェクトを自動検出して一括操作するのはそう難しくないけど、増えるマテリアルの件のせいで大丈夫かこれって躊躇してます
こんなもんどう考えてもUnity公式が頑張って解決せえやユーザーになげんな!!なクソ仕様
ただマテリアル一つ1.9kbの微々たるサイズ、

インスタンス作ったらマテリアルが無条件で増えるわけではなく、上記のエミッションもスライダー動かしてもマテリアルは増えず、Awake後に作られた同一プレハブの複製だったらマテリアル増えないみたいな場合もあるので、
そこまで気にすることないのかなあ…
Commenti