ひつじTips

技術系いろいろつまみ食います。

VRM モデルのスケールを変更すると,髪揺れがおかしくなる件の対策

f:id:mu-777:20190104025438p:plain
https://dwango.github.io/vrm/

VRMなかなか楽しいっすねぇ~

VTuber的な使い方以外にも,常にモデルデータを求めているであろう個人ゲーム開発屋さんなども使いやすいのではないでしょうか??VRoidStudioでお手軽に作って,UniVRMでUnityに簡単インポートすれば,それでゲームも作れちゃいますしね~

ただ,そこで微妙にUniVRMのバグっぽい挙動なのが,VRMモデルのスケールを変更したときです.

VRMのルート(VRMMetaなどのComponentがあるGameObject)のスケールを小さくすると,髪の毛が爆発しますw

f:id:mu-777:20190104033244p:plain

小さい方をアップでもう一度.

f:id:mu-777:20190104042328p:plain

えらいこっちゃですね.

まぁVRMのルートのGameObjectを選択すればわかるのですが,単純にSpringBorn用のColliderのRadiusがスケール変更に対応できていないっぽいだけですね.

f:id:mu-777:20190104042521p:plain



この記事の内容だけだとちゃんと解決できません!!

こちらにもうちょい正しい(と思われる)修正方法書いたのでこちらをどうぞ!!

mu-777.hatenablog.com



解決方法

「実際に物理演算に有効なColliderのサイズ」と「Gizmoのマゼンタ球のサイズ」はそれぞれ別のところで処理されているので,その2つの処理部分に修正を入れてやれば解決できます.

まずは「実際に物理演算に有効なColliderのサイズ」の修正から.

VRM/UniVRM/Scripts/SpringBone/VRMSpringBone.cs287行目あたりからを, 以下のように修正します.

                foreach (var group in ColliderGroups)
                {
+                   var globalScale = Mathf.Max(Mathf.Max(group.transform.lossyScale.x,
+                                                         group.transform.lossyScale.y),
+                                               transform.lossyScale.z);
                    if (group != null)
                    {
                        foreach (var collider in group.Colliders)
                        {
                            m_colliderList.Add(new SphereCollider
                            {
                                Position = group.transform.TransformPoint(collider.Offset),
-                               Radius = collider.Radius,
+                               Radius = collider.Radius * globalScale,
                            });
                        }
                    }
                }


あと,「Gizmoのマゼンタ球のサイズ」の修正は,VRM/UniVRM/Scripts/SpringBone/VRMSpringBoneColliderGroup.cs33行目あたりからを,以下のように修正.

            Gizmos.matrix = mat * Matrix4x4.Scale(new Vector3(
                1.0f / transform.lossyScale.x,
                1.0f / transform.lossyScale.y,
                1.0f / transform.lossyScale.z
                ));
+           var globalScale = Mathf.Max(Mathf.Max(transform.lossyScale.x,
+                                                 transform.lossyScale.y),
+                                       transform.lossyScale.z);

            foreach (var y in Colliders)
            {
-               Gizmos.DrawWireSphere(y.Offset, y.Radius);
+               Gizmos.DrawWireSphere(y.Offset, y.Radius * globalScale);
            }


これでOKです!

確認

上の修正を入れると,このような感じになります.

f:id:mu-777:20190104045001p:plain

小さい方をアップで見てもだいじょーぶ.Gizmoのマゼンタ球も小さくなっていることがわかります.

f:id:mu-777:20190104045115p:plain

最後に

この記事で使ったVRMは,僕がVRoidStudioで作ったVRMです!

hub.vroid.com

あおいちゃんかわいい!!!!!!!!
見てね!!!!!!!!!!