Unityで作ったアニメーションデータが「Missing」になってしまい動かなくなった!というのは多くの方が経験されていると思います。
今回はその問題について改善方法があるようなので紹介したいと思います。
はじめに
今回、UnityStoreで購入したファイルを利用していたのですが
開発の都合上、階層関係を変更する必要があったので修正したところ…
残念ながら大量のMissing!がでてしまいました…
今までなら諦めて一つずつ修正していくところですが、昔からよく起きるので誰か改善方法見つけてるんじゃ…!
と思い調べたところ…
ありました!
エディタ拡張機能を使って紹介されているサイトです。
今回はそのサイトの内容だけだと私の憎き「Missing」は修正できなかったので
紹介いただいているスクリプトにさらに修正点も加えて紹介していきたいと思います。
参考サイト
その解決方法を紹介いただいているサイトは
Unityっ子御用達の「テラシュールブログ」さんです。
この方法を参考にさせてもらって一度は解決、そして大喜びの私です。
ありがとうございます!
これで地獄の修正作業から解放されました。【Unity】AnimationClipのMissingなパスを見つけて解決しやすくするエディタ拡張 – テラシュールブログ https://t.co/f4dXd7PiHG
— Tadapy@ゲーム制作 (@tadapy88) August 9, 2020
ただこの後、また別の問題がおきてしまうのですよね…
問題点
階層が変わった時は問題なかったのですが
アニメーションで利用しているコンポーネントを消して
別の階層に移植したときに問題は起きたんです…
出ました!「Missing」
その時の私は無敵な気分だったので
「ふふふ」と笑いながら拡張機能を利用したところ
表示されたのはこの顔
(^ ^)b
この顔は変換完了時に出る顔です。
残念ながらこれは対応されていませんでした…
そして確認するとシンプルなスクリプトだったので自分で修正することにしました。
修正したスクリプト
修正するスクリプト「ReplaceMissingAnimationCurve.cs」です。
FindPath内でコンポーネントがあるかを確認する
“// 追加:コンポーネントがあるかを確認” というコメントの位置を確認してください。
// 省略 void FindPath () { // 省略 foreach (var clip in clips) { var bindings = AnimationUtility.GetCurveBindings (clip); foreach (var binding in bindings) { // 追加:コンポーネントがあるかを確認 Transform foundTransform = animator.transform.Find (binding.path); if ( foundTransform == null || (foundTransform != null && foundTransform.GetComponent(binding.type) == null) ) { missingPathList.Add (binding.path); missingCount++; } } // 省略 } // 省略 }
解説すると階層内からターゲットとなるTransformを検索しているのですが
元のソースコードのみだとコンポーネントの有無まで見れていません。
なのでその条件にコンポーネントがあるかを確認する処理を追加しています。
ルートがターゲットになるとエラーが出る
「追加:ルートにある要素を別階層のものに関連付けるために追加」
というコメント辺りの処理を確認してください。
ReplaceMissingAnimationCurve.cs
static void ReplacePath (AnimationClip[] clips, string oldPath, string newPath) { // 省略 foreach (var clip in clips) { // 省略 foreach (var binding in removeBindings) { var curve = AnimationUtility.GetEditorCurve (clip, binding); var newBinding = binding; // 追加:ルートにある要素を別階層のものに関連付けるために追加 newBinding.path = ( oldPath != "" ) ? newBinding.path.Replace(oldPath, newPath) : newPath; // 省略 } } } // 省略
AnimatorがついているGameObject(ルート)を指定するために空文字列を設定すると
“newBinding.path.Replace”という箇所でエラーが出ます。
なのでoldPathが空文字の場合ははそのままパスを書き込む処理にしました。
最後に
いかがでしたでしょうか?
私のルートのコンポーネントを参照していた憎き「Missing」はこれで消えました…
同じようにMissingでお悩みの方はぜひご活用いただければ幸いです。
ではここまでお読みいただきありがとうございました。
コメント