2015年6月4日木曜日

SDユニティちゃん活用その6 ~SDユニティちゃんにユレモノを自動設定する~

BlenderでFBXエクスポート&UnityでFBXインポートしたSDユニティちゃんにユレモノ(服/髪揺れ)を設定するメモ。

今回はこれをスクリプトを用いて自動で設定します。






環境

Windows7x64
Unity 5.0.1f1 Personal
Blender2.74(x64)
SDユニティちゃん 3Dモデルデータ Download ver1.0。(2015/5時点最新)

※作業中素材には『ユニティちゃんライセンス』で提供されるコンテンツを利用しています。




前提

前記事まででBlenderでエクスポート&UnityでインポートしたSDユニティちゃんのモデルを使います。
Unityのプロジェクト状態も同様です。

参考:
SDユニティちゃん活用その1 ~Blenderでインポート~  
SDユニティちゃん活用その3 ~Blenderでエクスポート~
SDユニティちゃん活用その4 ~Blender出力のFBXファイルをUnityでインポート~




便宜上インポート後のAssetの位置は次のようにしています。

/Assets/Blender_SDUnityChan/blender_SDUnityChan



※作業上、配布原本のモデルと分けて識別する為、文中でこれを「Blender版SDユニティちゃん」と表記している場合があります。




ユレモノについて

公式配布のSDユニティちゃんは髪や服が揺れます。

しかしBlnederでFBXエクスポート&UnityでFBXインポートしたモデルは、そのままでは全く揺れません。


公式配布のPrefabsフォルダにあるSDユニティちゃんにはユレモノ関連の設定がされています。

自分でFBXファイルをインポートしたモデルはそれらが未設定です。
自分で追加設定すれば揺らすことができます。


しかし設定部位が結構多い為、インポートする度に手動で全て行うのは正直、



疲れます( ゚Д゚;)



と、いうことで自動でユレモノ設定するコード(C#)を書きました。




準備

前回までのブログで作成済みのUnityプロジェクトを開いている状態とします。

プロジェクトの状態を簡単に言うと、
  • 公式配布SDユニティちゃんのシーン SD_unitychan_humanoid を読込済み。
  • 前記事のBlenderで出力済みのSDユニティちゃんのFBXファイルをUnityでインポート済み。
と、いった感じです。


次のURLでサイトを開き(GitHub)、

https://github.com/maruton/Tools_for_SDUnityChan


右下付近の「Download.ZIP」でダウンロード&展開。

Setup_Yuremono_for_SDUnityChan.cs をUnityのAssetにドラッグ&ドロップして追加しておきます。




ユレモノ設定

便宜上各モデルの呼称を以下としています。

  • SD_unitychan_humanoid : 公式配布のPrefabsフォルダにあるモデル。
  • blender_SDUnityChan :  Blender経由でUnityにインポートしたモデル。
    (当ブログ記事で今までにインポートしたもの)




設定を行っていきます。
  1. SD_unitychan_humanoid がシーンにあることを確認
    もしなければシーンに配置します。
    Position <0,0,0>、Rotation <0,0,0>を確認。
    ※ずれていたら設定する。

  2. blender_SDUnityChan をシーン上に配置する。
    Position <0,0,0>、Rotation <0,0,0>を確認。
    ※ずれていたら設定する。

  3. blender_SDUnityChan のスクリプト IdleChanger をDisable
    もしも IdleChanger が未追加なら何もせず次のステップへ。
    既に IdleChanger が追加済みの場合は Inspector上からチェックを外す。


  4. シーン上blender_SDUnityChan のアニメーションコントローラ確認
    Inspector上Animator のController欄に SD_unitychan_motion_humanoid の設定を確認。
    なければ設定する。SD_unitychan_humanoidの設定と同じ)。
    Inspector上Animatorのチェックを外してDisableにする。

  5. 空のGameObjectをシーンに配置する。
    CTRL+SHIDT+N で空のGameObjectを追加。
    ダウンロード&展開済みの Setup_Yuremono_for_SDUnityChan をドラッグ&ドロップする。
    Setup_Yuremono_for_SDUnityChan の、
    • Go_Original へシーン上の  SD_unitychan_humanoid をドラッグ&ドロップする。
    • Go_Target  へシーン上の blender_SDUnityChan をドラッグ&ドロップする。

  6. Unity を Playする
    Consoleウィンドウに、 START: と表示された後、 COMPLETE:  と表示されたら設定が完了しています。
    ※ERROR とか not found などが表示されていた場合はシーン上のアバターの構造に問題があるか、 Setup_Yuremono_for_SDUnityChan の Go_Original と Go_Target の設定を再確認してください。

    だいたい一瞬で表示されます。 これでユレモノ自動設定が完了しています。

  7. シーン上の blender_SDUnityChan をAssetにドラッグ&ドロップ
    この状態で(UnityがPlay状態のまま)、シーン上の blender_SDUnityChan をAsset(フォルダ Assets/Blender_SDUnityChan/Prefab あたりに)にドラッグ&ドロップします。

    ユレモノ設定済み状態のままでAssetに保存されます。
    blender_SDUnityChan 1  とリネームします

  8. Unity のPlayを停止します。

  9. blender_SDUnityChan 1 をシーンに配置
    Inspector上から以下のコンポーネントにチェックを入れてEnableにします。

    • Animator
    • SpringManager  (スクリプト)
    • IdleChanger (スクリプト)

    IdleChanger
    が未追加の場合は追加します。

    シーン上の blender_SDUnityChan 1blender_SDUnityChan_yuremono にリネームします。


    • シーン上の blender_SDUnityChan_yuremono をAsset(フォルダ Assets/Blender_SDUnityChan/Prefab あたりに)にドラッグ&ドロップします。

      以後このモデルを使えば、ユレモノ設定済み状態で使えます。

    あとはシーン上の他のSDユニティちゃんのモデルを削除した上で、先程Assetに保存した、blender_SDUnityChan_yuremono をシーンに配置してUnity を Play。

    GUIボタンで NEXT、BACKを押すと、髪や服もゆれます♪ O(≧▽≦)O ワーイ♪


    Consoleに
    'blender_SDUnityChan_yuremono' AnimationEvent 'OnCallChangeFace' has no receiver! Are you missing a component?
    と表示されているのは、FaceUpdateスクリプトをコンポーネントに追加していない為です。追加すれば消えます。
    しかし現在追加しても表情は動きません。いずれこれも対策したいと思います。




    一応Android上でも動くことは確認していますが意味がなさそうなので、ユレモノ設定済みのモデルをAssetに拾ってから使う方が良いと思います。




    補足1


    スクリプトの動作は簡単に言うと SD_unitychan_humanoidblender_SDUnityChan を2つ並べて、クローン化してるようなものです。
    (実際は少し面倒なこともしてます)


    □ モデルの差異


    • SD_unitychan_humanoid : 公式配布のPrefabsフォルダにあるモデル。
    • blender_SDUnityChan :  Blender経由でUnityにインポートしたモデル。
      (当ブログ記事で今までにインポートしたもの)

    この2つのモデルにはObject構成にいろいろと差異があります。同一ではありません。



    一言でいえば「Blenderを経由している」ことに起因していると思いますが、大別すると2点。
    1. SD_unitychan_humanoidにはユレモノ対応する為のCollider用 Object等がある。blender_SDUnityChanには無い。

    2. BlenderでFBXファイル インポートした際、ローカル軸向きが強制的に補正されてボーンの先端が強制的にY+になる様子。Blenderの仕様の為、回避不能みたいです。
      これにより blender_SDUnityChanSD_unitychan_humanoid とは異なるローカル軸向きになってしまう子Objectがあります。

      さらにいわゆるXYZ軸向きの右手/左手云々な話しも絡んでます。
      (OpenGL系 vs DirectX系)

    この辺に対応しつつクローン化してる、という感じです。



    □ スクリプト

    公式配布パッケージに含まれている SpringManagerSpringBoneSpringCollider の3つがユレモノ用スクリプトです。

    ユレモノ用スクリプトは blender_SDUnityChanで不足しているObjectも参照しているので、まずは全てのObjectを存在させないとユレモノ用スクリプトを追加できません。

    なのでまずは双方の子Objectを全比較して不足分を抽出し blender_SDUnityChan に追加しています。
    追加した子ObjectのPositionを決定する為に、雛形のSD_unitychan_humanoid を同座標に置いて、ごにょごにょしています。


    ユレモノ接続の向き(ローカル軸)を、ユレモノ用スクリプトに設定するパラメータ(BoneAxis)があるのですが、前述通り双方のモデルでローカル軸の向きに違いがある為、雛形のSD_unitychan_humanoid からそのままコピーでは使えません。


    当初変換方法を考えて演算で導くつもりでしたが、面倒になったので blender_SDUnityChan 専用にデータテーブル化して片付けています

    ココが、

    SDユニティちゃん活用その1 ~Blenderでインポート~
    SDユニティちゃん活用その3 ~Blenderでエクスポート~

    の手順に合致してインポート/エクスポートしていないとズレる可能性がある要因です。


    子Objectの構造が整った後にユレモノ用スクリプトの追加していくわけですが、相互に参照し合う箇所がある為、単純に追加していくと途中でユレモノ用スクリプトが動作しなくなって詰みます。

    原本のユレモノ用スクリプトのコードには手を付けたくなかった為、追加する順番やスクリプトのRunningのDisable/Enableできりぬけています。


    普通サイズなユニティちゃんの時は汎用性を考えすぎた余りにボーン構造や揺れパラメータを全Object分テキストファイル出力、解析処理、設定時に読み込むなどで冗長になりすぎてました。
    しかも原本のユレモノ用スクリプトも改造していたのでボツ化。
    今回はシンプルに1スクリプトで実装。その分 blender_SDUnityChan 専用気味になっている結果です。





    補足2

    Blenderのインポートスケール、 エクスポートスケール、Unityでのインポート後のスケールを相互に調整しても全ての子Objectが公式配布のモデルと同じスケールにうまくできませんでした。
    (やり方がまだまずい可能性はありそうですが)
    公式配布元のFBXファイルは(多分)Mayaでエクスポートされている気配(?)で100倍云々の倍率もかかってるような点も絡みます。


    最も近い状態は、
    1. Blenderで100倍でインポート
    2. Blenderで1倍でエクスポート
    3.  Unityでインポート後、Scaleを0.01
    で、全子Objectのスケールは合うのですが、Faceがおかしくなります。
    またBlender上で100倍は扱いづらいので、これを0.01倍してもおかしくなります。

    この辺はまだまだ勉強不足感が否めません。 原因がわかればもう少しスマートに対応できるかもしれません。


    結果的に諸々の作業性も考えて各フェイズでのスケール値を決めた結果、しわよせがUnityインポート後の子Objectのスケールに寄っています。

    • body などのメッシュオブジェクトのスケール値が0.01になっている。
    • Character1_Reference オブジェクトのスケールが0.01になっている。
      この影響で配下の子Objectは全て0.01スケール。
    本来の公式配布モデルでは全て1.0スケールです。


    これの意味するところは、Unity上では Local Positionでの移動量にこのスケール値が関与しているということです。
    公式配布のものと100倍変わるということです。

    ここはちょっと気にいらないところですが、 Setup_Yuremono_for_SDUnityChan.cs ではこの倍率の影響を受けずに処理にしています。


    Unityのメカニムは賢くできていて、アニメーションはきちんと動作しています。
    角度にはスケールの影響がない様子なのと、子Objectのローカル軸向きの差異もHumanoidタイプ化で吸収してくれるようです、スバラシイ!メカニム。


    直接移動制御をしなければ影響はないだろう・・・という判断です。
    (仮に制御するとしても倍率を把握していればなんとかなる・・・と思います)



    実用性は

    作っておいて言うのもなんですが、あまりない気はしています(笑

    ちょっとやりたいことのワークフロー上、これができるとターンアラウンドが早い(ハズ)ので作ってみた感じです。



    0 件のコメント:

    コメントを投稿