テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】ImmediateWindowで複数のMaterialの設定を一括更新してみる

f:id:tsubaki_t1:20190210222630j:plain

今回はImmediateWindow(Preview)を使用して、複数のマテリアルの一括更新をやってみます。

正しい使い方では無いっぽいですが、正直な所すごくシックリする使い方でした。

Immediate Windowは開発効率を上げるツールではない

Immediate Windowは、ソースコードを記述したファイル無しで使い捨てコードを実行できるエディターです。ソースファイル無しにスクリプトの実行内容を評価したり、確認したりすることが出来ます。

主な用途は実行結果の確認で、「あれ、このコードの実行結果はどうなるんだっけ?」的な時に、ソースコード記述→エディターのコンパイル→実行といった手間を通さずにすばやく処理の動作を確認する機能みたいです。他のツールでよく見るコンソールのような「エディターに対して即時コマンドを実行し、開発効率を上げる的な用途ではない」と、マニュアルに記載されています。

It's not a tool aim at developement but rather debug scenarios or editor API discovery.

今ひとつイメージが付かないと思うので簡単な例を。例えば`string[] AssetDatabase.FindAssets( string filter );'というAPIがあります。これはプロジェクト内のFilterの条件に一致するファイルを見つけるというAPIです。このAPIを使用すれば、特定のファイルを簡単に取得できると…思うじゃん?

実際にスクリプトを記述して実行してみるとあら不思議、なんとGUIDで発行しています。これではPathとしてそのまま使用できないので AssetDatabase.GUIDToAssetPath(...)でさらに変換する必要があるね!というのが分かります。

f:id:tsubaki_t1:20190210224850j:plain
Immediate Windowの画面

こんな感じに「プロジェクトにソースコードを残さず、ちょっとしたコードの動きを確認出来る」便利ツールです。

なおPackageManagerで提供されてます。その他UIの説明については、下の記事が分かりやすいです。

baba-s.hatenablog.com

それでもエディターの作業効率化に使いたい

上で「エディターに対して即時コマンドを実行し、開発効率を上げる的な用途ではない」と書きました。

このImmediate Window、本質的にはECSのSystemのようなシリアライズしないオブジェクトの状態を確認したり、JobSystemで使用するような演算の数式を確認する物なんだろうと思いますが(Window > Analyticsの項目にありますし)、それでも「コンソール」に似ている本機能を見ると、どうしても作業効率化的な用途に使用したくなります。

そうだ、マテリアルの内容を差し替えてみよう

なので、実際に試してみました。やったことはタイトルの通り、「Materialの設定を一括変更する」という操作の自動化です。

Materialは同一シェーダーなら一括変更が可能なのですが、異なるシェーダー(例えばStandardシェーダーとStandard- Specular setupシェーダー等)が混じっていると、使用できなくなります。そこでスクリプトによる一括作業ですが、本格的なGUIを用意するのは面倒くさい…
と、こんなケースで使用するのに便利かなーと。

操作は「現在選択中のMaterialの"_MainTex"の内容を、特定の名前(今回はUnitychanIcon)を持つテクスチャに差し替える」というもの。

手順1. Immediate Windowを開く

まずはImmediate Windowを起動させます。

  1. window > package managerを開き、immediate windowを導入
  2. window > Analytics > Immediate Windowを開く

f:id:tsubaki_t1:20190210230545j:plain
Immediate Windowのパッケージ

今回の手順ではImmediate Windowは複数行で記述出来たほうが良いので、full script modeにして入力欄を大きくします。

  1. 右上のfull script modeボタンを押す

f:id:tsubaki_t1:20190210230720j:plain
full script modeボタンの位置

手順2.  実行するコードの入力

下のコードをImmediate Windowのスクリプト入力項目にコピペします。「編集する項目」は、必要に応じて編集します。

// 編集する項目 --- ここから
var 上書きに使用するテクスチャ = "t:Texture UnitychanIcon";
var 上書きする設定 = "_MainTex";
// ---  ここまで       
        
//変更しなくていい項目
var 操作対象の一覧 = Selection.objects; // Selection.objects = エディターで選択中のオブジェクト一覧
var 上書きするテクスチャ = AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(AssetDatabase.FindAssets(上書きに使用するテクスチャ)[0]));
foreach ( var 操作対象 in 操作対象の一覧)
{
    var 操作するマテリアル = 操作対象 as Material;
    if (操作対象 == null)
        continue;
    操作するマテリアル.SetTexture(上書きする設定, 上書きするテクスチャ);
}
AssetDatabase.Refresh();

"Done"

f:id:tsubaki_t1:20190210231330j:plain
設定後の画面

手順3.  コードを実行

コードを実行します。

  1. 設定を反映するマテリアルを全て選択する
  2. execute scriptボタンを押す

これでスクリプトが実行され、MainTextureが全てUnitychanIconのテクスチャに差し替わりました。

f:id:tsubaki_t1:20190210231657g:plain
スクリプトを実行する様子

なお、実際にどのテクスチャを使用したのかを確認したい場合、上書きするテクスチャと記述して実行すれば、使用したテクスチャのパラメーターを全て確認することが出来ます。これは以前の処理で使用したパラメーターが丸ごと残っている為です。なので、上のスクリプトで使用した変数「上書きするテクスチャ」を指定すれば、その中身が確認出来ます。(この動作では、文末の;は不要です)

これはResetボタンを押すまで残りますし、再定義した場合は上書きされます。

f:id:tsubaki_t1:20190210232214g:plain
スクリプトが使用したパラメーターを確認

Immediate Window熱い機能だね!でも少し使いづらすぎない?

Immediate Window、入力補完が効きません。たぶん仕様です。

Q: This is an overcomplicated design and too hard to use
A: Pull Requests are welcomed, whining is not

感想

ちょっとした数値の確認に便利な機能で、作業の自動化にチャレンジしてみました。こういった機能の方が有り難いのですが、ソレを素直に推奨しないのは何か理由があるのかもしれません。

とは言え、このアプローチが認められると「簡単な項目の組み合わせで、様々な作業が自動化出来る」可能性があります。PhotoshopやMayaと似たような感じとまでは行きませんが、「簡単なスクリプトテンプレートをググって組み合わせれば一括操作が実現出来る」という具合に。これはエディター拡張で云々するより非常に楽です。

一方、本来の使い方である「データを確認する」という用途の場合、便利かもしれませんが「入力補完が出来ない」という点で使い勝手が…ZapZapZap(おっと泣き言は禁止されています)

関連

顧客(私)が本当に求めていたもの

tips.hecomi.com

マニュアル

docs.unity3d.com