public void DrawGizmos()
 {
     if (force == null || !isActiveAndEnabled)
     {
         return;
     }
     Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
     if (Application.isPlaying)
     {
         Vector3 forceVector = force.GetForce(Time.time);
         float   width       = forceVector.magnitude * 0.2f;
         EZSoftBoneUtility.DrawGizmosArrow(Vector3.zero, forceVector, width, Vector3.up);
         EZSoftBoneUtility.DrawGizmosArrow(Vector3.zero, forceVector, width, Vector3.right);
         Gizmos.DrawRay(Vector3.zero, forceVector);
     }
     else
     {
         Vector3 forceVector = new Vector3(0, 0, force.force);
         float   width       = force.force * 0.2f;
         EZSoftBoneUtility.DrawGizmosArrow(Vector3.zero, forceVector, width, Vector3.up);
         EZSoftBoneUtility.DrawGizmosArrow(Vector3.zero, forceVector, width, Vector3.right);
         Gizmos.DrawRay(Vector3.zero, forceVector);
     }
     Gizmos.DrawWireCube(new Vector3(0, 0, force.force), force.turbulence * 2);
 }
示例#2
0
        private void OnDrawGizmosSelected()
        {
            Vector3 force0 = GetForce(0) * 50;
            float   width  = force0.magnitude * 0.2f;

            Gizmos.DrawRay(transform.position, force0);
            EZSoftBoneUtility.DrawGizmosArrow(transform.position, force0, width, transform.up);
            EZSoftBoneUtility.DrawGizmosArrow(transform.position, force0, width, transform.right);
        }
示例#3
0
 public override void Collide(ref Vector3 position, float spacing)
 {
     if (referenceCollider is SphereCollider)
     {
         SphereCollider collider = referenceCollider as SphereCollider;
         if (insideMode)
         {
             EZSoftBoneUtility.PointInsideSphere(ref position, collider, spacing + margin);
         }
         else
         {
             EZSoftBoneUtility.PointOutsideSphere(ref position, collider, spacing + margin);
         }
     }
     else if (referenceCollider is CapsuleCollider)
     {
         CapsuleCollider collider = referenceCollider as CapsuleCollider;
         if (insideMode)
         {
             EZSoftBoneUtility.PointInsideCapsule(ref position, collider, spacing + margin);
         }
         else
         {
             EZSoftBoneUtility.PointOutsideCapsule(ref position, collider, spacing + margin);
         }
     }
     else if (referenceCollider is BoxCollider)
     {
         BoxCollider collider = referenceCollider as BoxCollider;
         if (insideMode)
         {
             EZSoftBoneUtility.PointInsideBox(ref position, collider, spacing + margin);
         }
         else
         {
             EZSoftBoneUtility.PointOutsideBox(ref position, collider, spacing + margin);
         }
     }
     else if (referenceCollider is MeshCollider)
     {
         if (!CheckConvex(referenceCollider as MeshCollider))
         {
             Debug.LogError("Non-Convex Mesh Collider is not supported", this);
             enabled = false;
             return;
         }
         if (insideMode)
         {
             Debug.LogError("Inside Mode On Mesh Collider is not supported", this);
             insideMode = false;
             return;
         }
         EZSoftBoneUtility.PointOutsideCollider(ref position, referenceCollider, spacing + margin);
     }
 }
示例#4
0
 public override void Collide(ref Vector3 position, float spacing)
 {
     if (insideMode)
     {
         EZSoftBoneUtility.PointInsideCylinder(ref position, transform, spacing + margin);
     }
     else
     {
         EZSoftBoneUtility.PointOutsideCylinder(ref position, transform, spacing + margin);
     }
 }
示例#5
0
        public void DrawGizmos(Transform gizmosReference, Transform forceSpace)
        {
            Vector3 force0 = GetForce(0, forceSpace) * UnityEditor.HandleUtility.GetHandleSize(gizmosReference.position);
            float   width  = force0.magnitude * 0.2f;

            if (forceSpace == null)
            {
                Gizmos.DrawRay(gizmosReference.position, force0);
                EZSoftBoneUtility.DrawGizmosArrow(gizmosReference.position, force0, width, Vector3.up);
                EZSoftBoneUtility.DrawGizmosArrow(gizmosReference.position, force0, width, Vector3.right);
            }
            else
            {
                Gizmos.DrawRay(gizmosReference.position, force0);
                EZSoftBoneUtility.DrawGizmosArrow(gizmosReference.position, force0, width, gizmosReference.up);
                EZSoftBoneUtility.DrawGizmosArrow(gizmosReference.position, force0, width, gizmosReference.right);
            }
        }
示例#6
0
        private void OnDrawGizmosSelected()
        {
            Vector3 center, direction;
            float   radius, height;

            EZSoftBoneUtility.GetCylinderParams(transform, out center, out direction, out radius, out height);
            UnityEditor.Handles.color  = Color.red;
            UnityEditor.Handles.matrix = Matrix4x4.identity;
            Vector3 p0 = center + direction * height;
            Vector3 p1 = center - direction * height;

            UnityEditor.Handles.DrawWireDisc(p0, transform.up, radius);
            UnityEditor.Handles.DrawWireDisc(p1, transform.up, radius);
            UnityEditor.Handles.matrix *= Matrix4x4.Translate(transform.forward * radius);
            UnityEditor.Handles.DrawLine(p0, p1);
            UnityEditor.Handles.matrix *= Matrix4x4.Translate(-transform.forward * 2 * radius);
            UnityEditor.Handles.DrawLine(p0, p1);
            UnityEditor.Handles.matrix *= Matrix4x4.Translate((transform.right + transform.forward) * radius);
            UnityEditor.Handles.DrawLine(p0, p1);
            UnityEditor.Handles.matrix *= Matrix4x4.Translate(-transform.right * 2 * radius);
            UnityEditor.Handles.DrawLine(p0, p1);
        }
示例#7
0
        public void DrawGizmos(Vector3 gizmosPosition, Transform forceSpace, float scale)
        {
            Vector3 forceVector, turbulenceVector;

            if (forceSpace != null)
            {
                forceVector      = forceSpace.TransformDirection(direction) * scale;
                turbulenceVector = forceSpace.TransformDirection(turbulence) * scale;
                float width = forceVector.magnitude * 0.2f;
                EZSoftBoneUtility.DrawGizmosArrow(gizmosPosition, forceVector, width, forceSpace.up);
                EZSoftBoneUtility.DrawGizmosArrow(gizmosPosition, forceVector, width, forceSpace.right);
            }
            else
            {
                forceVector      = direction * scale;
                turbulenceVector = turbulence * scale;
                float width = forceVector.magnitude * 0.2f;
                EZSoftBoneUtility.DrawGizmosArrow(gizmosPosition, forceVector, width, Vector3.up);
                EZSoftBoneUtility.DrawGizmosArrow(gizmosPosition, forceVector, width, Vector3.right);
            }
            Gizmos.DrawRay(gizmosPosition, forceVector);
            Gizmos.DrawWireCube(gizmosPosition + forceVector + turbulenceVector * 0.5f, turbulenceVector);
        }
示例#8
0
        private void UpdateNode(Bone bone)
        {
            if (bone.depth > startDepth)
            {
                Vector3 oldWorldPosition, newWorldPosition;
                oldWorldPosition = newWorldPosition = bone.worldPosition;

                // Damping (inertia attenuation)
                if (bone.speed.sqrMagnitude < sleepThreshold)
                {
                    bone.speed = Vector3.zero;
                }
                else
                {
                    newWorldPosition += bone.speed * Time.deltaTime * (1 - bone.damping);
                }

                // Resistance (force resistance)
                Vector3 force = gravity;
                if (gravityAligner != null)
                {
                    Vector3 alignedDir  = gravityAligner.TransformDirection(gravity).normalized;
                    Vector3 globalDir   = gravity.normalized;
                    float   attenuation = Mathf.Acos(Vector3.Dot(alignedDir, globalDir)) / Mathf.PI;
                    force *= attenuation;
                }
                if (forceModule != null)
                {
                    force += forceModule.GetForce(bone.normalizedLength, forceSpace);
                }
                force.x          *= transform.localScale.x;
                force.y          *= transform.localScale.y;
                force.z          *= transform.localScale.z;
                newWorldPosition += force * (1 - bone.resistance) / iterations;

                // Stiffness (shape keeper)
                Vector3 parentOffset = bone.parentBone.worldPosition - bone.parentBone.transform.position;
                Vector3 expectedPos  = bone.parentBone.transform.TransformPoint(bone.originalLocalPosition) + parentOffset;
                newWorldPosition = Vector3.Lerp(newWorldPosition, expectedPos, bone.stiffness / iterations);

                // Slackness (length keeper)
                Vector3 nodeDir    = (newWorldPosition - bone.parentBone.worldPosition).normalized;
                float   nodeLength = bone.parentBone.transform.TransformVector(bone.originalLocalPosition).magnitude;
                nodeDir = bone.parentBone.worldPosition + nodeDir * nodeLength;
                // Siblings
                if (siblingConstraints != UnificationMode.None)
                {
                    int constraints = 1;
                    if (bone.leftBone != null)
                    {
                        Vector3 leftDir    = (newWorldPosition - bone.leftBone.worldPosition).normalized;
                        float   leftLength = bone.transform.TransformVector(bone.positionToLeft).magnitude;
                        leftDir  = bone.leftBone.worldPosition + leftDir * leftLength;
                        nodeDir += leftDir;
                        constraints++;
                    }
                    if (bone.rightBone != null)
                    {
                        Vector3 rightDir    = (newWorldPosition - bone.rightBone.worldPosition).normalized;
                        float   rightLength = bone.transform.TransformVector(bone.positionToRight).magnitude;
                        rightDir = bone.rightBone.worldPosition + rightDir * rightLength;
                        nodeDir += rightDir;
                        constraints++;
                    }
                    nodeDir /= constraints;
                }
                newWorldPosition = Vector3.Lerp(nodeDir, newWorldPosition, bone.slackness / iterations * Time.deltaTime);

                // Collision
                if (bone.radius > 0)
                {
                    foreach (EZSoftBoneColliderBase collider in EZSoftBoneColliderBase.EnabledColliders)
                    {
                        if (bone.transform != collider.transform && collisionLayers.Contains(collider.gameObject.layer))
                        {
                            collider.Collide(ref newWorldPosition, bone.radius);
                        }
                    }
                    foreach (Collider collider in extraColliders)
                    {
                        if (bone.transform != collider.transform && collider.enabled)
                        {
                            EZSoftBoneUtility.PointOutsideCollider(ref newWorldPosition, collider, bone.radius);
                        }
                    }
                }

                bone.speed         = (newWorldPosition - oldWorldPosition) / Time.deltaTime; //
                bone.worldPosition = newWorldPosition;
            }
            else
            {
                bone.transform.localPosition = bone.originalLocalPosition;
                bone.worldPosition           = bone.transform.position;
            }

            for (int i = 0; i < bone.childBones.Count; i++)
            {
                UpdateNode(bone.childBones[i]);
            }
        }
示例#9
0
        private void UpdateBones(Bone bone, float deltaTime)
        {
            if (bone.depth > startDepth)
            {
                Vector3 oldWorldPosition, newWorldPosition, expectedPosition;
                oldWorldPosition = newWorldPosition = bone.worldPosition;

                // Resistance (force resistance)
                Vector3 force = globalForce;
                if (forceModule != null && forceModule.isActiveAndEnabled)
                {
                    force += forceModule.GetForce(bone.normalizedLength) * forceScale;
                }
                if (customForce != null)
                {
                    force += customForce(bone.normalizedLength);
                }
                force.x    *= transform.localScale.x;
                force.y    *= transform.localScale.y;
                force.z    *= transform.localScale.z;
                bone.speed += force * (1 - bone.resistance) / iterations;

                // Damping (inertia attenuation)
                bone.speed *= 1 - bone.damping;
                if (bone.speed.sqrMagnitude > sleepThreshold)
                {
                    newWorldPosition += bone.speed * deltaTime;
                }

                // Stiffness (shape keeper)
                Vector3 parentMovement = bone.parentBone.worldPosition - bone.parentBone.transform.position;
                expectedPosition = bone.parentBone.transform.TransformPoint(bone.localPosition) + parentMovement;
                newWorldPosition = Vector3.Lerp(newWorldPosition, expectedPosition, bone.stiffness / iterations);

                // Slackness (length keeper)
                // Length needs to be calculated with TransformVector to match runtime scaling
                Vector3 dirToParent    = (newWorldPosition - bone.parentBone.worldPosition).normalized;
                float   lengthToParent = bone.parentBone.transform.TransformVector(bone.localPosition).magnitude;
                expectedPosition = bone.parentBone.worldPosition + dirToParent * lengthToParent;
                int lengthConstraints = 1;
                // Sibling constraints
                if (siblingConstraints != UnificationMode.None)
                {
                    if (bone.leftBone != null)
                    {
                        Vector3 dirToLeft    = (newWorldPosition - bone.leftBone.worldPosition).normalized;
                        float   lengthToLeft = bone.transform.TransformVector(bone.leftPosition).magnitude;
                        expectedPosition += bone.leftBone.worldPosition + dirToLeft * lengthToLeft;
                        lengthConstraints++;
                    }
                    if (bone.rightBone != null)
                    {
                        Vector3 dirToRight    = (newWorldPosition - bone.rightBone.worldPosition).normalized;
                        float   lengthToRight = bone.transform.TransformVector(bone.rightPosition).magnitude;
                        expectedPosition += bone.rightBone.worldPosition + dirToRight * lengthToRight;
                        lengthConstraints++;
                    }
                }
                expectedPosition /= lengthConstraints;
                newWorldPosition  = Vector3.Lerp(expectedPosition, newWorldPosition, bone.slackness / iterations);

                // Collision
                if (bone.radius > 0)
                {
                    foreach (EZSoftBoneColliderBase collider in EZSoftBoneColliderBase.EnabledColliders)
                    {
                        if (bone.transform != collider.transform && collisionLayers.Contains(collider.gameObject.layer))
                        {
                            collider.Collide(ref newWorldPosition, bone.radius);
                        }
                    }
                    foreach (Collider collider in extraColliders)
                    {
                        if (bone.transform != collider.transform && collider.enabled)
                        {
                            EZSoftBoneUtility.PointOutsideCollider(ref newWorldPosition, collider, bone.radius);
                        }
                    }
                }

                bone.speed         = (bone.speed + (newWorldPosition - oldWorldPosition) / deltaTime) * 0.5f;
                bone.worldPosition = newWorldPosition;
            }
            else
            {
                bone.worldPosition = bone.transform.position;
            }

            for (int i = 0; i < bone.childBones.Count; i++)
            {
                UpdateBones(bone.childBones[i], deltaTime);
            }
        }