diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs index 52eccc274..bc33b17e0 100644 --- a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10Runtime.cs @@ -1,11 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using UniGLTF; -using UniGLTF.Utils; using UnityEngine; -using UniVRM10.FastSpringBones.Blittables; -using UniVRM10.FastSpringBones.System; namespace UniVRM10 { @@ -23,11 +17,6 @@ namespace UniVRM10 { private readonly Vrm10Instance m_instance; private readonly Transform m_head; - private readonly FastSpringBoneService m_fastSpringBoneService; - private readonly IReadOnlyDictionary m_defaultTransformStates; - - private FastSpringBoneBuffer m_fastSpringBoneBuffer; - private BlittableExternalData m_externalData; /// /// Control Rig may be null. @@ -38,17 +27,14 @@ namespace UniVRM10 public IVrm10Constraint[] Constraints { get; } public Vrm10RuntimeExpression Expression { get; } public Vrm10RuntimeLookAt LookAt { get; } - + public Vrm10RuntimeSpringBone SpringBone { get; } public IVrm10Animation VrmAnimation { get; set; } + [Obsolete("use Vrm10Runtime.SpringBone.ExternalForce")] public Vector3 ExternalForce { - get => m_externalData.ExternalForce; - set - { - m_externalData.ExternalForce = value; - m_fastSpringBoneBuffer.ExternalData = m_externalData; - } + get { return SpringBone.ExternalForce; } + set { SpringBone.ExternalForce = value; } } public Vrm10Runtime(Vrm10Instance instance, bool useControlRig) @@ -72,117 +58,20 @@ namespace UniVRM10 Constraints = instance.GetComponentsInChildren(); LookAt = new Vrm10RuntimeLookAt(instance.Vrm.LookAt, instance.Humanoid, ControlRig); Expression = new Vrm10RuntimeExpression(instance, LookAt.EyeDirectionApplicable); - - var gltfInstance = instance.GetComponent(); - if (gltfInstance != null) - { - // ランタイムインポートならここに到達してゼロコストになる - m_defaultTransformStates = gltfInstance.InitialTransformStates; - } - else - { - // エディタでプレハブ配置してる奴ならこっちに到達して収集する - m_defaultTransformStates = instance.GetComponentsInChildren() - .ToDictionary(tf => tf, tf => new TransformState(tf)); - } - - // NOTE: FastSpringBoneService は UnitTest などでは動作しない - if (Application.isPlaying) - { - m_fastSpringBoneService = FastSpringBoneService.Instance; - m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_instance.SpringBone); - m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer); - } + SpringBone = new Vrm10RuntimeSpringBone(instance); } public void Dispose() { ControlRig?.Dispose(); - m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer); - m_fastSpringBoneBuffer.Dispose(); + SpringBone.Dispose(); } - /// - /// このVRMに紐づくSpringBone関連のバッファを再構築する - /// ランタイム実行時にSpringBoneに対して変更を行いたいときは、このメソッドを明示的に呼ぶ必要がある - /// + [Obsolete("use Vrm10Runtime.SpringBone.ReconstructSpringBone")] public void ReconstructSpringBone() { - m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer); - - m_fastSpringBoneBuffer.Dispose(); - m_fastSpringBoneBuffer = CreateFastSpringBoneBuffer(m_instance.SpringBone); - - m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer); + SpringBone.ReconstructSpringBone(); } - - private FastSpringBoneBuffer CreateFastSpringBoneBuffer(Vrm10InstanceSpringBone springBone) - { - return new FastSpringBoneBuffer( - springBone.Springs.Select(spring => new FastSpringBoneSpring - { - center = spring.Center, - colliders = spring.ColliderGroups - .SelectMany(group => group.Colliders) - .Select(collider => new FastSpringBoneCollider - { - Transform = collider.transform, - Collider = new BlittableCollider - { - offset = collider.Offset, - radius = collider.Radius, - tailOrNormal = collider.TailOrNormal, - colliderType = TranslateColliderType(collider.ColliderType) - } - }).ToArray(), - joints = spring.Joints - .Select(joint => new FastSpringBoneJoint - { - Transform = joint.transform, - Joint = new BlittableJoint - { - radius = joint.m_jointRadius, - dragForce = joint.m_dragForce, - gravityDir = joint.m_gravityDir, - gravityPower = joint.m_gravityPower, - stiffnessForce = joint.m_stiffnessForce - }, - DefaultLocalRotation = GetOrAddDefaultTransformState(joint.transform).LocalRotation, - }).ToArray(), - }).ToArray(), - m_externalData); - } - - private TransformState GetOrAddDefaultTransformState(Transform tf) - { - if (m_defaultTransformStates.TryGetValue(tf, out var defaultTransformState)) - { - return defaultTransformState; - } - - Debug.LogWarning($"{tf.name} does not exist on load."); - return new TransformState(null); - } - - private static BlittableColliderType TranslateColliderType(VRM10SpringBoneColliderTypes colliderType) - { - switch (colliderType) - { - case VRM10SpringBoneColliderTypes.Sphere: - return BlittableColliderType.Sphere; - case VRM10SpringBoneColliderTypes.Capsule: - return BlittableColliderType.Capsule; - case VRM10SpringBoneColliderTypes.Plane: - return BlittableColliderType.Plane; - case VRM10SpringBoneColliderTypes.SphereInside: - return BlittableColliderType.SphereInside; - case VRM10SpringBoneColliderTypes.CapsuleInside: - return BlittableColliderType.CapsuleInside; - default: - throw new ArgumentOutOfRangeException(); - } - } - /// /// 毎フレーム関連コンポーネントを解決する /// @@ -241,4 +130,4 @@ namespace UniVRM10 Expression.Process(eyeDirection); } } -} +} \ No newline at end of file diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeSpringBone .cs b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeSpringBone .cs new file mode 100644 index 000000000..2820b1e49 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeSpringBone .cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UniGLTF; +using UniGLTF.Utils; +using UnityEngine; +using UniVRM10.FastSpringBones.Blittables; +using UniVRM10.FastSpringBones.System; + +namespace UniVRM10 +{ + public class Vrm10RuntimeSpringBone : IDisposable + { + private readonly Vrm10Instance m_instance; + private readonly IReadOnlyDictionary m_defaultTransformStates; + private readonly FastSpringBoneService m_fastSpringBoneService; + private FastSpringBoneSpring[] m_springs; + private Quaternion[] m_initialLocalRotations; + private FastSpringBoneBuffer m_fastSpringBoneBuffer; + public Vector3 ExternalForce + { + get => m_fastSpringBoneBuffer.ExternalForce; + set => m_fastSpringBoneBuffer.ExternalForce = value; + } + public bool IsSpringBoneEnabled + { + get => m_fastSpringBoneBuffer.IsSpringBoneEnabled; + set => m_fastSpringBoneBuffer.IsSpringBoneEnabled = value; + } + + internal Vrm10RuntimeSpringBone(Vrm10Instance instance) + { + m_instance = instance; + + var gltfInstance = instance.GetComponent(); + if (gltfInstance != null) + { + // ランタイムインポートならここに到達してゼロコストになる + m_defaultTransformStates = gltfInstance.InitialTransformStates; + } + else + { + // エディタでプレハブ配置してる奴ならこっちに到達して収集する + m_defaultTransformStates = instance.GetComponentsInChildren() + .ToDictionary(tf => tf, tf => new TransformState(tf)); + } + + // NOTE: FastSpringBoneService は UnitTest などでは動作しない + if (Application.isPlaying) + { + m_fastSpringBoneService = FastSpringBoneService.Instance; + ReconstructSpringBone(); + } + } + + public void Dispose() + { + m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer); + m_fastSpringBoneBuffer.Dispose(); + } + + /// + /// このVRMに紐づくSpringBone関連のバッファを再構築する + /// ランタイム実行時にSpringBoneに対して変更を行いたいときは、このメソッドを明示的に呼ぶ必要がある + /// + public void ReconstructSpringBone() + { + // rerelase + if (m_fastSpringBoneBuffer != null) + { + m_fastSpringBoneService.BufferCombiner.Unregister(m_fastSpringBoneBuffer); + m_fastSpringBoneBuffer.Dispose(); + } + + // create(Spring情報の再収集。設定変更の反映) + m_springs = m_instance.SpringBone.Springs.Select(spring => new FastSpringBoneSpring + { + center = spring.Center, + colliders = spring.ColliderGroups + .SelectMany(group => group.Colliders) + .Select(collider => new FastSpringBoneCollider + { + Transform = collider.transform, + Collider = new BlittableCollider + { + offset = collider.Offset, + radius = collider.Radius, + tailOrNormal = collider.TailOrNormal, + colliderType = TranslateColliderType(collider.ColliderType) + } + }).ToArray(), + joints = spring.Joints + .Select(joint => new FastSpringBoneJoint + { + Transform = joint.transform, + Joint = new BlittableJoint + { + radius = joint.m_jointRadius, + dragForce = joint.m_dragForce, + gravityDir = joint.m_gravityDir, + gravityPower = joint.m_gravityPower, + stiffnessForce = joint.m_stiffnessForce + }, + DefaultLocalRotation = GetOrAddDefaultTransformState(joint.transform).LocalRotation, + }).ToArray(), + }).ToArray(); + + // DOTS buffer 構築 + m_fastSpringBoneBuffer = new FastSpringBoneBuffer(m_springs); + m_fastSpringBoneService.BufferCombiner.Register(m_fastSpringBoneBuffer); + // reset 用の初期状態の記録 + m_initialLocalRotations = m_fastSpringBoneBuffer.Transforms.Select(x => x.localRotation).ToArray(); + } + + private TransformState GetOrAddDefaultTransformState(Transform tf) + { + if (m_defaultTransformStates.TryGetValue(tf, out var defaultTransformState)) + { + return defaultTransformState; + } + + Debug.LogWarning($"{tf.name} does not exist on load."); + return new TransformState(null); + } + + private static BlittableColliderType TranslateColliderType(VRM10SpringBoneColliderTypes colliderType) + { + switch (colliderType) + { + case VRM10SpringBoneColliderTypes.Sphere: + return BlittableColliderType.Sphere; + case VRM10SpringBoneColliderTypes.Capsule: + return BlittableColliderType.Capsule; + case VRM10SpringBoneColliderTypes.Plane: + return BlittableColliderType.Plane; + case VRM10SpringBoneColliderTypes.SphereInside: + return BlittableColliderType.SphereInside; + case VRM10SpringBoneColliderTypes.CapsuleInside: + return BlittableColliderType.CapsuleInside; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public void RestoreInitialTransform() + { + // Spring の joint に対応する transform の回転を初期状態 + for (int i = 0; i < m_fastSpringBoneBuffer.Transforms.Length; ++i) + { + var transform = m_fastSpringBoneBuffer.Transforms[i]; + transform.localRotation = m_initialLocalRotations[i]; + } + + // 初期状態にしたtransformを使って spring logic を構築 + List blittableLogics = new(); + foreach (var spring in m_springs) + { + blittableLogics.AddRange( + FastSpringBoneBuffer.LogicFromTransform(m_fastSpringBoneBuffer.Transforms, spring)); + } + // DOTS バッファーを更新 + m_fastSpringBoneBuffer.SyncAndZeroVelocity(blittableLogics); + } + } +} \ No newline at end of file diff --git a/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeSpringBone .cs.meta b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeSpringBone .cs.meta new file mode 100644 index 000000000..7772228d7 --- /dev/null +++ b/Assets/VRM10/Runtime/Components/Vrm10Runtime/Vrm10RuntimeSpringBone .cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2f3312577381e824eac9514c892e3cbc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/VRM10/Runtime/FastSpringBone/Blittables/BlittableExternalData.cs b/Assets/VRM10/Runtime/FastSpringBone/Blittables/BlittableExternalData.cs index f55dd5d97..d79789c5f 100644 --- a/Assets/VRM10/Runtime/FastSpringBone/Blittables/BlittableExternalData.cs +++ b/Assets/VRM10/Runtime/FastSpringBone/Blittables/BlittableExternalData.cs @@ -8,5 +8,10 @@ namespace UniVRM10.FastSpringBones.Blittables public struct BlittableExternalData { public Vector3 ExternalForce; + + /// + /// if false, spring bone is paused. + /// + public bool IsSpringBoneEnabled; } } \ No newline at end of file diff --git a/Assets/VRM10/Runtime/FastSpringBone/InputPorts/FastSpringBoneBuffer.cs b/Assets/VRM10/Runtime/FastSpringBone/InputPorts/FastSpringBoneBuffer.cs index c91391354..6d1c55c8b 100644 --- a/Assets/VRM10/Runtime/FastSpringBone/InputPorts/FastSpringBoneBuffer.cs +++ b/Assets/VRM10/Runtime/FastSpringBone/InputPorts/FastSpringBoneBuffer.cs @@ -26,24 +26,39 @@ namespace UniVRM10.FastSpringBones.System // NOTE: これは更新頻度が高くバッチングが難しいため、ランダムアクセスを許容してメモリへ直接アクセスする // 生のヒープ領域は扱いにくいので長さ1のNativeArrayで代用 private NativeArray _externalData; - - public BlittableExternalData ExternalData + public Vector3 ExternalForce { - get => _externalData[0]; - set => _externalData[0] = value; + get => _externalData[0].ExternalForce; + set + { + _externalData[0] = new BlittableExternalData + { + ExternalForce = value, + IsSpringBoneEnabled = _externalData[0].IsSpringBoneEnabled, + }; + } + } + public bool IsSpringBoneEnabled + { + get => _externalData[0].IsSpringBoneEnabled; + set + { + _externalData[0] = new BlittableExternalData + { + ExternalForce = _externalData[0].ExternalForce, + IsSpringBoneEnabled = value, + }; + } } - public unsafe FastSpringBoneBuffer(IReadOnlyList springs, - BlittableExternalData externalData, - bool simulateLastBone = false) + /// + /// Joint, Collider, Center の Transform のリスト + /// - 重複を除去 + /// + /// + /// + static Transform[] MakeFlattenTransformList(FastSpringBoneSpring[] springs) { - Profiler.BeginSample("FastSpringBone.ConstructBuffers"); - - _externalData = new NativeArray(1, Allocator.Persistent); - ExternalData = externalData; - - // Transformの列挙 - Profiler.BeginSample("FastSpringBone.ConstructBuffers.ConstructTransformBuffer"); var transformHashSet = new HashSet(); foreach (var spring in springs) { @@ -60,19 +75,26 @@ namespace UniVRM10.FastSpringBones.System if (spring.center != null) transformHashSet.Add(spring.center); } + var Transforms = transformHashSet.ToArray(); + return Transforms; + } - var transforms = transformHashSet.ToArray(); - var transformIndexDictionary = transforms.Select((trs, index) => (trs, index)) - .ToDictionary(tuple => tuple.trs, tuple => tuple.index); - Profiler.EndSample(); - - // 各種bufferの構築 - Profiler.BeginSample("FastSpringBone.ConstructBuffers.ConstructBuffers"); - var blittableColliders = new List(); - var blittableJoints = new List(); - var blittableSprings = new List(); - var blittableLogics = new List(); + public unsafe FastSpringBoneBuffer(FastSpringBoneSpring[] springs) + { + Profiler.BeginSample("FastSpringBone.ConstructBuffers.BufferBuilder"); + Transforms = MakeFlattenTransformList(springs); + _externalData = new NativeArray(1, Allocator.Persistent); + _externalData[0] = new BlittableExternalData + { + ExternalForce = Vector3.zero, + IsSpringBoneEnabled = true, + }; + var externalDataPtr = (BlittableExternalData*)_externalData.GetUnsafePtr(); + List blittableSprings = new(); + List blittableJoints = new(); + List blittableColliders = new(); + List blittableLogics = new(); foreach (var spring in springs) { var blittableSpring = new BlittableSpring @@ -85,91 +107,95 @@ namespace UniVRM10.FastSpringBones.System logicSpan = new BlittableSpan { startIndex = blittableJoints.Count, - count = simulateLastBone ? spring.joints.Length : spring.joints.Length - 1, + count = spring.joints.Length - 1, }, - centerTransformIndex = spring.center ? transformIndexDictionary[spring.center] : -1, - ExternalData = (BlittableExternalData*) _externalData.GetUnsafePtr() + centerTransformIndex = Array.IndexOf(Transforms, spring.center), + ExternalData = externalDataPtr, }; blittableSprings.Add(blittableSpring); blittableColliders.AddRange(spring.colliders.Select(collider => { var blittable = collider.Collider; - blittable.transformIndex = transformIndexDictionary[collider.Transform]; + blittable.transformIndex = Array.IndexOf(Transforms, collider.Transform); return blittable; })); blittableJoints.AddRange(spring.joints - .Take(simulateLastBone ? spring.joints.Length : spring.joints.Length - 1).Select(joint => + .Take(spring.joints.Length - 1).Select(joint => { var blittable = joint.Joint; return blittable; })); - for (var i = 0; i < (simulateLastBone ? spring.joints.Length : spring.joints.Length - 1); ++i) - { - var joint = spring.joints[i]; - var tailJoint = i + 1 < spring.joints.Length ? spring.joints[i + 1] : (FastSpringBoneJoint?) null; - var parentJoint = i - 1 >= 0 ? spring.joints[i - 1] : (FastSpringBoneJoint?) null; - var localPosition = Vector3.zero; - if (tailJoint.HasValue) - { - localPosition = tailJoint.Value.Transform.localPosition; - } - else - { - if (parentJoint.HasValue) - { - var delta = joint.Transform.position - parentJoint.Value.Transform.position; - localPosition = - joint.Transform.worldToLocalMatrix.MultiplyPoint(joint.Transform.position + delta); - } - else - { - localPosition = Vector3.down; - } - } - - var scale = tailJoint.HasValue ? tailJoint.Value.Transform.lossyScale : joint.Transform.lossyScale; - var localChildPosition = - new Vector3( - localPosition.x * scale.x, - localPosition.y * scale.y, - localPosition.z * scale.z - ); - - var worldChildPosition = joint.Transform.TransformPoint(localChildPosition); - var currentTail = spring.center != null - ? spring.center.InverseTransformPoint(worldChildPosition) - : worldChildPosition; - var parent = joint.Transform.parent; - blittableLogics.Add(new BlittableLogic - { - headTransformIndex = transformIndexDictionary[joint.Transform], - parentTransformIndex = parent != null ? transformIndexDictionary[parent] : -1, - currentTail = currentTail, - prevTail = currentTail, - localRotation = joint.DefaultLocalRotation, - boneAxis = localChildPosition.normalized, - length = localChildPosition.magnitude - }); - } + blittableLogics.AddRange(LogicFromTransform(Transforms, spring)); } - Profiler.EndSample(); - - // 各種bufferの初期化 - Profiler.BeginSample("FastSpringBone.ConstructBuffers.ConstructNativeArrays"); Springs = new NativeArray(blittableSprings.ToArray(), Allocator.Persistent); - Joints = new NativeArray(blittableJoints.ToArray(), Allocator.Persistent); Colliders = new NativeArray(blittableColliders.ToArray(), Allocator.Persistent); Logics = new NativeArray(blittableLogics.ToArray(), Allocator.Persistent); - - BlittableTransforms = new NativeArray(transforms.Length, Allocator.Persistent); - Transforms = transforms.ToArray(); + BlittableTransforms = new NativeArray(Transforms.Length, Allocator.Persistent); Profiler.EndSample(); + } - Profiler.EndSample(); + /// + /// Transform の現状から Logic を作成する。 + /// + /// + /// + /// joint index + /// + public static IEnumerable LogicFromTransform(Transform[] Transforms, FastSpringBoneSpring spring) + { + // vrm-1.0 では末端の joint は tail で処理対象でないのに注意! + for (int i = 0; i < spring.joints.Length - 1; ++i) + { + var joint = spring.joints[i]; + var tailJoint = i + 1 < spring.joints.Length ? spring.joints[i + 1] : (FastSpringBoneJoint?)null; + var parentJoint = i - 1 >= 0 ? spring.joints[i - 1] : (FastSpringBoneJoint?)null; + var localPosition = Vector3.zero; + if (tailJoint.HasValue) + { + localPosition = tailJoint.Value.Transform.localPosition; + } + else + { + if (parentJoint.HasValue) + { + var delta = joint.Transform.position - parentJoint.Value.Transform.position; + localPosition = + joint.Transform.worldToLocalMatrix.MultiplyPoint(joint.Transform.position + delta); + } + else + { + localPosition = Vector3.down; + } + } + + var scale = tailJoint.HasValue ? tailJoint.Value.Transform.lossyScale : joint.Transform.lossyScale; + var localChildPosition = new Vector3( + localPosition.x * scale.x, + localPosition.y * scale.y, + localPosition.z * scale.z + ); + + var worldChildPosition = joint.Transform.TransformPoint(localChildPosition); + var currentTail = spring.center != null + ? spring.center.InverseTransformPoint(worldChildPosition) + : worldChildPosition; + var parent = joint.Transform.parent; + + yield return new BlittableLogic + { + headTransformIndex = Array.IndexOf(Transforms, joint.Transform), + parentTransformIndex = Array.IndexOf(Transforms, parent), + currentTail = currentTail, + prevTail = currentTail, // same with currentTail. velocity zero. + localRotation = joint.DefaultLocalRotation, + boneAxis = localChildPosition.normalized, + length = localChildPosition.magnitude + }; + } } public void Dispose() @@ -183,5 +209,16 @@ namespace UniVRM10.FastSpringBones.System Logics.Dispose(); _externalData.Dispose(); } + + public void SyncAndZeroVelocity(IReadOnlyList logics) + { + var dst = Logics; + for (int i = 0; i < logics.Count; ++i) + { + var l = logics[i]; + l.prevTail = l.currentTail; + dst[i] = l; + } + } } } \ No newline at end of file diff --git a/Assets/VRM10/Runtime/FastSpringBone/System/UpdateFastSpringBoneJob.cs b/Assets/VRM10/Runtime/FastSpringBone/System/UpdateFastSpringBoneJob.cs index 4c7009d09..cc0694514 100644 --- a/Assets/VRM10/Runtime/FastSpringBone/System/UpdateFastSpringBoneJob.cs +++ b/Assets/VRM10/Runtime/FastSpringBone/System/UpdateFastSpringBoneJob.cs @@ -147,8 +147,16 @@ namespace UniVRM10.FastSpringBones.System headTransform.localRotation = headTransform.rotation; } - // 値をバッファに戻す - Transforms[logic.headTransformIndex + transformIndexOffset] = headTransform; + if (spring.ExternalData->IsSpringBoneEnabled) + { + // SpringBone の結果を Transform に反映する + Transforms[logic.headTransformIndex + transformIndexOffset] = headTransform; + } + else + { + // SpringBone の結果を Transform に反映しないが logic の更新は継続する。 + // 再開したときに暴れない。 + } Logics[logicIndex] = logic; } } diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs b/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs index e5d5882b5..11d47dac9 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs +++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10Loaded.cs @@ -1,6 +1,5 @@ using System; using UniGLTF; -using UniGLTF.Utils; using UnityEngine; namespace UniVRM10.VRM10Viewer diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity b/Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity index 1346fb42d..54855ea3b 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity +++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10Viewer.unity @@ -232,7 +232,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 339774397} - m_RootOrder: 14 + m_RootOrder: 16 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -773,7 +773,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 339774397} - m_RootOrder: 4 + m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1236,13 +1236,15 @@ RectTransform: - {fileID: 1621794411} - {fileID: 2009818432} - {fileID: 168425995} - - {fileID: 1307084561} - {fileID: 224350191} - {fileID: 1791103379} - {fileID: 1311520909} - - {fileID: 1557052150} - - {fileID: 1767706907} + - {fileID: 1307084561} - {fileID: 974864191} + - {fileID: 1767706907} + - {fileID: 1557052150} + - {fileID: 1728528388} + - {fileID: 704896193} - {fileID: 597950322} - {fileID: 935566651} - {fileID: 634488421} @@ -1822,7 +1824,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 339774397} - m_RootOrder: 10 + m_RootOrder: 12 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1903,7 +1905,7 @@ RectTransform: - {fileID: 154330168} - {fileID: 1954133885} m_Father: {fileID: 339774397} - m_RootOrder: 16 + m_RootOrder: 18 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1990,7 +1992,7 @@ RectTransform: - {fileID: 2010083454} - {fileID: 1081455630} m_Father: {fileID: 339774397} - m_RootOrder: 12 + m_RootOrder: 14 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -2246,6 +2248,128 @@ MonoBehaviour: m_ChildScaleWidth: 0 m_ChildScaleHeight: 0 m_ReverseArrangement: 0 +--- !u!1 &704896192 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 704896193} + - component: {fileID: 704896196} + - component: {fileID: 704896195} + - component: {fileID: 704896194} + m_Layer: 5 + m_Name: ResetSpringBone + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &704896193 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 704896192} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 983782643} + m_Father: {fileID: 339774397} + m_RootOrder: 11 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 162, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &704896194 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 704896192} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 704896195} + m_OnClick: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &704896195 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 704896192} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &704896196 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 704896192} + m_CullTransparentMesh: 0 --- !u!1 &773923918 GameObject: m_ObjectHideFlags: 0 @@ -3397,7 +3521,7 @@ RectTransform: - {fileID: 175751363} - {fileID: 1904789319} m_Father: {fileID: 339774397} - m_RootOrder: 11 + m_RootOrder: 13 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -3435,7 +3559,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 339774397} - m_RootOrder: 9 + m_RootOrder: 7 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -3484,6 +3608,88 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 974864190} m_CullTransparentMesh: 0 +--- !u!1 &983782642 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 983782643} + - component: {fileID: 983782645} + - component: {fileID: 983782644} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &983782643 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 983782642} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 704896193} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &983782644 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 983782642} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: 'ResetSpring + +' +--- !u!222 &983782645 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 983782642} + m_CullTransparentMesh: 0 --- !u!1 &1007924635 GameObject: m_ObjectHideFlags: 0 @@ -4600,6 +4806,86 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1242458542} m_CullTransparentMesh: 0 +--- !u!1 &1258907230 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1258907231} + - component: {fileID: 1258907233} + - component: {fileID: 1258907232} + m_Layer: 5 + m_Name: Label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1258907231 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1258907230} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1728528388} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 9, y: -0.5} + m_SizeDelta: {x: -28, y: -3} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1258907232 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1258907230} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: PauseSpringBone +--- !u!222 &1258907233 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1258907230} + m_CullTransparentMesh: 1 --- !u!1 &1268276254 GameObject: m_ObjectHideFlags: 0 @@ -4869,7 +5155,7 @@ RectTransform: m_Children: - {fileID: 910859648} m_Father: {fileID: 339774397} - m_RootOrder: 3 + m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -5066,7 +5352,7 @@ RectTransform: - {fileID: 1866921958} - {fileID: 1767669911} m_Father: {fileID: 339774397} - m_RootOrder: 6 + m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -5363,7 +5649,7 @@ RectTransform: - {fileID: 452923209} - {fileID: 2090837017} m_Father: {fileID: 339774397} - m_RootOrder: 15 + m_RootOrder: 17 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -5498,6 +5784,83 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1476033060} m_CullTransparentMesh: 0 +--- !u!1 &1519258557 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1519258558} + - component: {fileID: 1519258560} + - component: {fileID: 1519258559} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1519258558 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1519258557} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2055567529} + m_Father: {fileID: 1728528388} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -10} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1519258559 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1519258557} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1519258560 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1519258557} + m_CullTransparentMesh: 1 --- !u!1 &1557052149 GameObject: m_ObjectHideFlags: 0 @@ -5510,7 +5873,7 @@ GameObject: - component: {fileID: 1557052152} - component: {fileID: 1557052151} m_Layer: 5 - m_Name: _ + m_Name: _SpringBone_ m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -5529,7 +5892,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 339774397} - m_RootOrder: 7 + m_RootOrder: 9 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -5569,7 +5932,7 @@ MonoBehaviour: m_HorizontalOverflow: 0 m_VerticalOverflow: 0 m_LineSpacing: 1 - m_Text: + m_Text: SpringBone --- !u!222 &1557052152 CanvasRenderer: m_ObjectHideFlags: 0 @@ -5920,6 +6283,93 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1636340563} m_CullTransparentMesh: 0 +--- !u!1 &1728528387 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1728528388} + - component: {fileID: 1728528389} + m_Layer: 5 + m_Name: PauseSpringBone + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1728528388 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1728528387} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1519258558} + - {fileID: 1258907231} + m_Father: {fileID: 339774397} + m_RootOrder: 10 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 160, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1728528389 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1728528387} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1519258559} + toggleTransition: 1 + graphic: {fileID: 2055567530} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 0 --- !u!1 &1761414315 GameObject: m_ObjectHideFlags: 0 @@ -6199,7 +6649,7 @@ RectTransform: - {fileID: 62367395} - {fileID: 1037763549} m_Father: {fileID: 339774397} - m_RootOrder: 13 + m_RootOrder: 15 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -6373,6 +6823,8 @@ MonoBehaviour: m_openMotion: {fileID: 168425996} m_pastePose: {fileID: 1307084564} m_showBoxMan: {fileID: 1767706908} + m_pauseSpringBone: {fileID: 1728528389} + m_resetSpringBone: {fileID: 704896194} m_enableLipSync: {fileID: 935566650} m_enableAutoBlink: {fileID: 634488422} m_enableAutoExpression: {fileID: 1767738855} @@ -6431,7 +6883,7 @@ RectTransform: - {fileID: 1166391799} - {fileID: 1140410864} m_Father: {fileID: 339774397} - m_RootOrder: 5 + m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -7243,6 +7695,82 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2010083453} m_CullTransparentMesh: 0 +--- !u!1 &2055567528 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2055567529} + - component: {fileID: 2055567531} + - component: {fileID: 2055567530} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2055567529 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2055567528} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1519258558} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2055567530 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2055567528} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10901, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2055567531 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2055567528} + m_CullTransparentMesh: 1 --- !u!1 &2090837016 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs index f4ecd3445..f0f842ae2 100644 --- a/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs +++ b/Assets/VRM10_Samples/VRM10Viewer/VRM10ViewerUI.cs @@ -27,6 +27,12 @@ namespace UniVRM10.VRM10Viewer [SerializeField] Toggle m_showBoxMan = default; + [SerializeField] + Toggle m_pauseSpringBone = default; + + [SerializeField] + Button m_resetSpringBone = default; + [SerializeField] Toggle m_enableLipSync = default; @@ -252,6 +258,7 @@ namespace UniVRM10.VRM10Viewer m_openModel = buttons.First(x => x.name == "OpenModel"); m_openMotion = buttons.First(x => x.name == "OpenMotion"); m_pastePose = buttons.First(x => x.name == "PastePose"); + m_resetSpringBone = buttons.First(x => x.name == "ResetSpringBone"); #if UNITY_2022_3_OR_NEWER var toggles = GameObject.FindObjectsByType(FindObjectsSortMode.InstanceID); @@ -259,6 +266,7 @@ namespace UniVRM10.VRM10Viewer var toggles = GameObject.FindObjectsOfType(); #endif m_showBoxMan = toggles.First(x => x.name == "ShowBoxMan"); + m_pauseSpringBone = toggles.First(x => x.name == "PauseSpringBone"); m_enableLipSync = toggles.First(x => x.name == "EnableLipSync"); m_enableAutoBlink = toggles.First(x => x.name == "EnableAutoBlink"); m_enableAutoExpression = toggles.First(x => x.name == "EnableAutoExpression"); @@ -347,6 +355,7 @@ namespace UniVRM10.VRM10Viewer m_openModel.onClick.AddListener(OnOpenModelClicked); m_openMotion.onClick.AddListener(OnOpenMotionClicked); m_pastePose.onClick.AddListener(OnPastePoseClicked); + m_resetSpringBone.onClick.AddListener(OnResetSpringBoneClicked); // load initial bvh if (m_motion != null) @@ -393,18 +402,20 @@ namespace UniVRM10.VRM10Viewer m_loaded.EnableLipSyncValue = m_enableLipSync.isOn; m_loaded.EnableBlinkValue = m_enableAutoBlink.isOn; m_loaded.EnableAutoExpressionValue = m_enableAutoExpression.isOn; - } - if (m_loaded != null) - { - if (m_ui.IsTPose) + if (m_loaded.Runtime != null) { - m_loaded.Runtime.VrmAnimation = TPose; - } - else if (Motion != null) - { - // Automatically retarget in Vrm10Runtime.Process - m_loaded.Runtime.VrmAnimation = Motion; + if (m_ui.IsTPose) + { + m_loaded.Runtime.VrmAnimation = TPose; + } + else if (Motion != null) + { + // Automatically retarget in Vrm10Runtime.Process + m_loaded.Runtime.VrmAnimation = Motion; + } + + m_loaded.Runtime.SpringBone.IsSpringBoneEnabled = !m_pauseSpringBone.isOn; } } } @@ -484,6 +495,17 @@ namespace UniVRM10.VRM10Viewer } } + void OnResetSpringBoneClicked() + { + if (m_loaded != null) + { + if (m_loaded.Runtime != null) + { + m_loaded.Runtime.SpringBone.RestoreInitialTransform(); + } + } + } + static IMaterialDescriptorGenerator GetVrmMaterialDescriptorGenerator(bool useUrp) { if (useUrp)