AssetPostprocessor完全に理解した

41.7K Views

March 31, 22

スライド概要

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

AssetPostprocessor完全に理解した 2022/03/31 henjiganai(木宮 杏)

2.

自己紹介 ● ● ● ● henjiganai(木宮 杏) 一応ITエンジニア 最初henjiganaiでGitHubとか取っていた が呼びにくい&判別しにくいという問題 があったため 好きな方で呼んでください

3.

最近の趣味 ● ● ● ● ● VRChat用のアバター作成中 アバターやワールドを作るとVRChatへ のログイン時間が激減する問題 エルデンリングクリアしました Bloodborneで新キャラ作成中 星の瞳の狩人証届きました ○ めちゃくちゃ綺麗ですね

4.

はじめに ● ● 最近のVRChatのアップデートは凄いですね これらのアップデートに対応するために直近でUnityを触っている方も多いのでは?

5.

はじめに ● ● Unityのエディター拡張使っていますか? 皆さんはこれらの操作を手動で行っていませんか? fbxファイルのAnimation TypeをHumanoidに変 更 Streaming Mipmapsのチェックをオン

6.

はじめに ● ● 3Dモデルやテクスチャの修正が発生するたびにインポート設定を修正するのが面倒じ ゃない? もっといい方法あるよ!

7.

AssetPostprocessorを使おう ● ● ● エディター拡張の一種 アセットインポート時の処理をフックする インポート前とインポート後に独自のスクリプトを実行することが可能

8.

AssetPostprocessorとは アセットインポート時の処理をフックする アセットをインポートする前とインポートした後に任意の処理を実行することができる ● OnPreprocess~(例:OnPreprocessModel、OnPreprocessAnimation) ○ ● アセットをインポートする前に呼び出される →インポート時の設定を変更するときに使用する OnPostprocess~(例:OnPostprocessModel、OnPostprocessAudio) ○ アセットがインポートされた後に呼び出される →インポートされたアセットに対して変更をしたいときに使用する

9.

AssetPostprocessorとは アセットインポート時の処理をフックする アセットをインポートする前とインポートした後に任意の処理を実行することができる ● OnPostprocessAllAssets ○ 全てのアセットのインポートが完了した後に呼び出される 詳細はUnity公式のドキュメントを見てください https://docs.unity3d.com/ja/current/ScriptReference/AssetPostprocessor.html

10.

AssetPostprocessorの処理の流れ(例1) 画像をインポートした場合

11.

AssetPostprocessorの処理の流れ(例2) アニメーションが付いていないFBXファイルをインポートした場合

12.

実際に使ってみた 1. AnimationTypeをHumanoidに設定 2. Blend Shape NormalsをNoneに設定 3. Mecanimのマッピングをコンソールに

13.

実際に使ってみた(1) 1. AnimationTypeをHumanoidに設定 2. Blend Shape NormalsをNoneに設定 VRChatでよくあるこの二つの設定をスクリプトで変更してみる

14.

設定方法 ● ● ● ModelImporterを使う https://docs.unity3d.com/ja/current/ScriptReference/ModelImporter.html Blend Shape Normals ○ importBlendShapeNormalsにModelImporterNormals.Noneを設定 Animation Type ○ animationTypeにModelImporterAnimationType.Humanを設定

15.

実際に使ってみた(1) 実際のコードがこちら public class FBXImportSample : AssetPostprocessor { void OnPreprocessModel() { ModelImporter modelImporter = assetImporter as ModelImporter; modelImporter.importBlendShapeNormals = ModelImporterNormals.None; modelImporter.animationType = ModelImporterAnimationType.Human; } }

16.

実際に使ってみた(1) 実はこれだけでは実際の運用の時に不足がある 皆さんわかりますか? public class FBXImportSample : AssetPostprocessor { void OnPreprocessModel() { ModelImporter modelImporter = assetImporter as ModelImporter; modelImporter.importBlendShapeNormals = ModelImporterNormals.None; modelImporter.animationType = ModelImporterAnimationType.Human; } }

17.

問題点 ● ● 最初のコードでは初回インポートか2回目以降のインポートかをチェックしていない 既にUnity Projects内にあるFBXファイルを再度インポートしたときも処理が実行して しまう →初回インポートしたときだけ処理が走ってほしい

18.
[beta]
初回インポートかを検出する
●

AssetImporter.importSettingsMissingを使う
https://docs.unity3d.com/jp/current/ScriptReference/AssetImporter-importSettingsMissing.html

●
●

インポートされたアセットに.metaファイルが提供されていない場合true
→初回インポート時は作成されていないので必ずtrueになる
2回目以降のインポート時やreimportを選択して再度インポートした場合はfalseになる
public class FBXImportSample : AssetPostprocessor
{
v oid OnPreprocessModel()
{
ModelImporter modelImporter = assetImporter as ModelImporter;
if (!modelImporter.importSettingsMissing)
{
return:
}

modelImporter.importBlendShapeNormals = ModelImporterNormals.None;
modelImporter.animationTy pe = ModelImporterAnimationTy pe.Human;
}

}

19.

実際に使ってみた(2) 3. Mecanimのマッピングをコンソールに FBXファイルインポート時にマッピングがずれていることが多々あるので確認したい

20.

実際に使ってみた(2) ● ModelImporter.humanDescriptionを使う https://docs.unity3d.com/ja/current/ScriptReference/ModelImporter-humanDescription.html https://docs.unity3d.com/ja/current/ScriptReference/HumanDescription.html ● HumanBone[] HumanDescription.human ○ Mecanim ボーン名とリグのボーン名の間におけるマッピング ここにマッピング情報が入っている

21.

HumanBoneを細かく見てみる https://docs.unity3d.com/ja/2018.4/ScriptReference/HumanBone.html ● ● humanName:モデルにおけるボーンのマッピング元となるMecanimのヒューマノイ ド型ボーン名 boneName:Mecanimのヒューマノイド型ボーンがマッピングされたボーン名 humanName boneName

22.
[beta]
実際に使ってみた(2)
実際のコードがこちら
public class FBXImportSample : AssetPostprocessor
{
void OnPostprocessModel(GameObject gameObject)
{
ModelImporter modelImporter = assetImporter as ModelImporter;
HumanDescription humanDescription = modelImporter.humanDescription;
foreach (HumanBone humanBone in humanDescription.human)
名前が不一致の場合青色で
{
コンソールにログを表示
bool isNotMatch = humanBone.humanName.Equals(humanBone.boneName);
var decorationColor = isNotMatch ? "<color=black>" : "<color=blue>";
Debug.Log($"{humanBone.humanName} : {decorationColor}{humanBone.boneName}</color>");
}
}
}

23.

実際にFBXファイルをインポートしてみた 一致していない部分が青色で出力される

24.

注意点 ● ● ● 何でも自動化すればいいわけではない 何度も繰り返す処理に向いている どのような場合に適用してほしいかを作成前に予め考える必要がある (画像だけ、最初のインポート時だけ等々)

25.

最後に ● ● ● ● エディター拡張は便利 開発の効率化ができる ヒューマンエラーを防ぐ 楽できるところは楽しよう 今回のコードはBOOTHとGitHubで公開してます 興味があれば見てみてください

26.

参考資料 ● ● ● ● Unityの各種公式ドキュメント https://docs.unity3d.com/ja/current/Manual/ExtendingTheEditor.html https://docs.unity3d.com/ja/current/ScriptReference/index.html エディター拡張入門 http://49.233.81.186/assetpostprocessor.html HumanDescriptionの各種値取得元の参考 https://teratail.com/questions/168728 MuscleNameの参考 https://gist.github.com/ikko615/eeaf9c1031a4055ff10a7c9a468b15e7