ShaderFXで作成されたMaterialのパラメーターを差し替えるツールを作る機会があったので、その際に利用したShaderFXのコマンドに関してまとめてみます。
- 自動的にShaderFXプラグインを読み込む
- ShaderFXコマンドのリファレンスを表示
- ShaderFXシェーダーを作成
- 既存のグラフを読み込み
- プロパティを書き換える
- 作成したShaderFXのMaterialを他のMaterialと差し替える
- おわり
ShaderFXで作成されたMaterialのパラメーターを差し替えるツールを作る機会があったので、その際に利用したShaderFXのコマンドに関してまとめてみます。
より正確に言うとsubprocessをGUIアプリケーションからクロスプラットフォームで使う方法です。
とはいえ実際のところMacだと特に困らないので、以下の内容はWindows向けの対応方法になります。
Mayaでテクスチャの参照があるシーンを作成時と異なるパスに配置した状態で開く、みたいなことってあると思うんですが、このときプロジェクトがちゃんとセットされていれば相対パスでテクスチャが参照されますよね。
このときの挙動の詳細や、それによって起こる問題の解決法を書いてみます。
melを説明した書籍は数あれど、プログラミングって敷居が高そう…文章読むの大変…という方々のために…
「マンガでわかるMELスクリプト」の連載を始めます🎉
シンプルなスクリプトから始めて、ちょっとした便利スクリプトの作成、日々の単純作業の自動化、独自のウィンドウの作成までをマンガとサンプルスクリプトで解説します!
また、さらに発展したツール作成を学びたい方のために、「マンガでわかるMayaPythonプログラミング」も連載予定です。
こちらではPython自体の解説はもちろん、PySideを用いたウィンドウの作成までを解説します。
4月より不定期連載開始ということがまことしやかに囁かれているとか、囁かれていないとか、作者の妄想だとか、様々な憶測が飛び交っておりますが、信じるかどうかは、あなた次第です!(どーん)
4/2追記:
エイプリルフールの嘘になるかどうかは僕の頑張り次第になります_(:3 」∠)_
Mayaでブレンドシェイプの作業をしててPre-deformation(FontOfChain)にしたつもりが実際はPost-deformationになってて、結果…
こんな悲しいことになることありませんか、ありませんか。
自前でクロスプラットフォーム対応してたのにこの機能Qtにあったのかよ!な小ネタです。
Unity2017.2からは各種DCCツールで設定したカスタムプロパティをFBXからImport出来るようになりました。
Animated Custom Properties
Various DCCs (e.g. Maya and 3DSMax) support adding custom properties (or attributes) to objects:
These will appear in the Animation Window as Animator properties, just like additional curves created from imported clips:
You can then use a MonoBehaviour to drive other Component properties, or use an AssetPostprocessor to bind your curves directly to any Component.
https://blogs.unity3d.com/2017/10/12/unity-2017-2-is-now-available/
尚、この記事における利用環境などは以下の通り。
というわけで早速やっていきます。
まずはMayaで適当なカスタムプロパティ(Extra Attributes)にキーを打っていきましょう。
今回は特定のマテリアルのアトリビュートを書き換えるようなものを考えます。
具体的にはユニティちゃんのこのパーツのハイライトのアトリビュートを変えてみようと思います。
こんな感じのコードを用意してスクリプトエディタなどで実行します。
引数は要件に応じて書き換えてください。
今回は変化が分かりやすいようにMaterialのcolorに割り当てたファイルノード(file2)のAlphaGainにキーを打っておいて、これをRoot_sphereノードにcustom_highcolor_powerという名前でコピーしています。
これをFBXエクスポートして準備完了です。
上のFBXをUnityでインポートしたのち、ImportSettingで「Animated Custom Properties」にチェックを入れて「Apply」を実行します。
これをAnimationウィンドウで見てみるとこのようになっています。
どうやらちゃんとインポートされているようです。やったぜ。
さて、これを果たしてどうやって反映すればいいのか…!
Unityのブログには以下のように書いてあります。
MonoBehaviourを使って他のコンポーネントプロパティを制御することができますし、どのコンポーネントにも直接カーブをバインドするのにAssetPostprocessorを使うこともできます。
https://blogs.unity3d.com/jp/2017/10/12/unity-2017-2-is-now-available/
お、おう。
Animationウィンドウをよく見てみるとAnimator.〜と書いてあります。
というわけで、正解はこう。
AnimatorControllerを作成、Stateを追加してMotionにインポートしたAnimationClipを指定したのち、Mayaで作ったアトリビュートと同じ名前、同じ型のパラメーターを追加してやればおっけーです。
深刻なドキュメント不足。
ただこれだけだとパラメーターが受け取れただけでUnityちゃんの頭のアレには何も起きないので、Materialに値を渡してやりましょう。
_rendererにはinspectorでMesh_SD_unitychan以下の_headを指定しています。
いざ実行…!
ヤッター。反映できたよー。
AnimatorControllerを使える環境ならこれでよいですが、PlayableAPIで制御する場合はパラメーターが使えない(自信ない)気がするので、これだと困ってしまいます。
となると、AnimationClipのカーブを書き換えたいなーとなるわけです。
まずはUnity2017.2の新機能を眺めてみましょう。
Asset Import: Added AssetPostprocessor.OnPostprocessGameObjectWithAnimatedUserProperties(GameObject go, EditorCurveBinding[] bindings) and void AssetPostprocessor.OnPostprocessAnimation(GameObject root,AnimationClip clip).
https://unity3d.com/jp/unity/whats-new/unity-2017.2.0
AssetPostprocessorにOnPostprocessGameObjectWithAnimatedUserPropertiesとOnPostprocessAnimationが追加されているようです。
今回はOnPostprocessAnimationを使ってみます。
もともとあったメソッドだとAnimationClipを取得するのがなかなかダルかったのですが、OnPostprocessAnimationは第二引数にAnimationClipが入ってくるのがよいですね。
まずはOnPostprocessGameObjectWithUserPropertiesでユーザー定義のアトリビュートのあるものをフックできるので、これで名前が一致するものをフィルタリングしてアセットパスをtargetsフィールドに格納しておきます。
次にOnPostprocessAnimationでこのtargetsに含まれるものがきたら対象のカーブのEditorCurveBindingを書き換え、AnimationClipとして保存しているような感じです。
curveBinding.path = "Mesh_SD_unitychan/_head"; curveBinding.type = typeof(SkinnedMeshRenderer); curveBinding.propertyName = "material._HighColor_Power";
pathはルートからの相対パス、typeは対象のクラス、propertyNameはそのまま格納するプロパティの名前を指定します。
目的のオブジェクトに対してそれぞれ何を指定したらいいか分からない場合、そのオブジェクトに対して新規でAnimationClipを作成して実際にAdd Propertyしてキーを打ってみて、生成された.animファイルをテキストとして開いてみるとよいです。
あとはこのAnimationClipをPlayableAPIを使って再生してやればおっけーです。
シンプル。
ただ、これだと割と構造が厳格に決まってないと厳しいのと、使い回しがきかなさそうな感じがします。
CurveBindingのtypeは何もビルトインされているクラスじゃないと駄目なわけではないので、自前で値を保持するクラスを作ってそいつを指定する、というのも可能です。
具体的には以下のようにします。
あとはこれに合わせてModelImporterのcurveBindingまわりの処理を以下のように変えてやります。
curveBinding.path = ""; curveBinding.type = typeof(CustomProperties); curveBinding.propertyName = "_highcolor_power";
Inspectorはこんな感じ。
これでCurveBindingのpathは空文字でよく、さらに値の反映先も自由に決められるので、AnimatorControllerで制御するときと大きく変わらない感じで管理できそうです。やったぜ。
OnPostprocessGameObjectWithAnimatedUserPropertiesは2回目のインポートのタイミングで確かにカスタムプロパティのEditorCurveBindingが処理に入ってくるんですけど、いまいち何に使えばよいか分からず。
事例が色々出てくることに期待しつつ、気が向いたらもうちょっと追ってみたいところ。
カスタムプロパティがサポートされたのは大変喜ばしいんですけど国内も国外も資料なさすぎてつらみがすごい…。
この作品はユニティちゃんライセンス条項の元に提供されています
スポンサーリンク