/// <summary> /// Computing look angles needed to look at target world position from this character /// </summary> public Vector2 ComputeAnglesTowards(Vector3 worldPosition) { // Direction towards target in different spaces Vector3 worldDirectionAndTargetAngles = (worldPosition - GetLookStartMeasurePosition()).normalized; // Supporting different axis orientation using matrix if (usingAxisCorrection) { worldDirectionAndTargetAngles = axisCorrectionMatrix.inverse.MultiplyVector(worldDirectionAndTargetAngles).normalized; worldDirectionAndTargetAngles = WrapVector(Quaternion.LookRotation(worldDirectionAndTargetAngles, axisCorrectionMatrix.MultiplyVector(ModelUpAxis).normalized).eulerAngles); } else // Easier calculations when using standard z - forward - y up { worldDirectionAndTargetAngles = BaseTransform.InverseTransformDirection(worldDirectionAndTargetAngles); worldDirectionAndTargetAngles = WrapVector(Quaternion.LookRotation(worldDirectionAndTargetAngles, BaseTransform.TransformDirection(ModelUpAxis)).eulerAngles); } return(worldDirectionAndTargetAngles); }
/// <summary> /// Main head look rotation calculations logics execution /// </summary> private void CalculateLookAnimation() { // Begin check for stop lokoing _stopLooking = false; // Stopping looking when object to follow is null if (FollowMode != EFFollowMode.FollowJustPosition) { if (ObjectToFollow == null) { if (MomentLookTransform == null) { _stopLooking = true; } } } Vector3 lookRotation; LookPositionUpdate(); LookWhenAboveGoBackCalculations(); // When stopping look, we don't want head to goo too fast onto forward look pose if (_stopLooking) { finalLookPosition = transform.TransformPoint(lookFreezeFocusPoint); } else { if (!BirdMode) { finalLookPosition = smoothLookPosition; } else { finalLookPosition = BirdTargetPosition; } } if (FixingPreset != EFAxisFixOrder.Parental) { #region Calculating target rotation and angles // If our target is out of max distance let's look at default direction if (LookState == EFHeadLookState.OutOfMaxDistance) { targetLookAngles = Vector3.MoveTowards(targetLookAngles, Vector3.zero, 1f + RotationSpeed); } else { // Direction towards target in different spaces Vector3 worldDirectionAndTargetAngles = (finalLookPosition - GetLookStartMeasurePosition()).normalized; // Supporting different axis orientation using matrix if (usingAxisCorrection) { worldDirectionAndTargetAngles = axisCorrectionMatrix.inverse.MultiplyVector(worldDirectionAndTargetAngles).normalized; worldDirectionAndTargetAngles = WrapVector(Quaternion.LookRotation(worldDirectionAndTargetAngles, axisCorrectionMatrix.MultiplyVector(ModelUpAxis).normalized).eulerAngles); } else // Easier calculations when using standard z - forward - y up { worldDirectionAndTargetAngles = BaseTransform.InverseTransformDirection(worldDirectionAndTargetAngles); worldDirectionAndTargetAngles = WrapVector(Quaternion.LookRotation(worldDirectionAndTargetAngles, BaseTransform.TransformDirection(ModelUpAxis)).eulerAngles); } targetLookAngles = worldDirectionAndTargetAngles; } Vector2 angles = targetLookAngles; angles = LimitAnglesCalculations(angles); AnimateAnglesTowards(angles); #endregion // Character rotation offset if (usingAxisCorrection) { Quaternion fromto = Quaternion.FromToRotation(Vector3.right, Vector3.Cross(Vector3.up, ModelForwardAxis)); fromto = Quaternion.Euler(finalLookAngles) * fromto * BaseTransform.rotation; lookRotation = fromto.eulerAngles; } else { lookRotation = finalLookAngles + BaseTransform.eulerAngles; } // Additional operations lookRotation += RotationOffset; lookRotation = ConvertFlippedAxes(lookRotation); } else // Universal correction method { lookRotation = LookRotationParental((finalLookPosition - GetLookStartMeasurePosition()).normalized).eulerAngles; lookRotation += RotationOffset; } if (!_stopLooking) { lookFreezeFocusPoint = BaseTransform.InverseTransformPoint(finalLookPosition); } targetLookRotation = Quaternion.Euler(lookRotation); SetTargetBonesRotations(); }
private void Gizmos_DrawClamping(float radius, Vector3 lookPos) { if (!_gizmosDrawingLimiting && DebugRays == false) { return; } Handles.matrix = BaseTransform.localToWorldMatrix; Vector3 startLook = GetLookStartMeasurePosition(); Vector3 startLookLocal = BaseTransform.InverseTransformPoint(startLook); Vector3 dir = (lookPos - startLook).normalized; if (LookState == EFHeadLookState.ClampedAngle) { Handles.color = new Color(1f, 1f, 0.1f, 0.7f); } else { Handles.color = new Color(0.3f, 1f, 0.1f, 0.7f); } //Gizmos.DrawLine(startLook, startLook + dir); Vector3 axisDir = BaseTransform.InverseTransformDirection(dir); axisDir.y = 0; axisDir.Normalize(); Handles.DrawLine(startLookLocal, startLookLocal + axisDir * radius); if (YRotationLimits != _gizmosLastVertClamp) { _gizmosVertAlpha = 1.5f; } // Vertical Handles.color = new Color(0.3f, 1f, 0.7f, 0.08f * Mathf.Min(_gizmosVertAlpha, 1f)); Handles.DrawSolidArc(startLookLocal, Vector3.right, ModelForwardAxis, YRotationLimits.y, radius / 1.2f); Handles.DrawSolidArc(startLookLocal, Vector3.right, ModelForwardAxis, YRotationLimits.x, radius / 1.2f); Handles.color = new Color(0.22f, .8f, 0.5f, 0.75f); Handles.DrawWireArc(startLookLocal, Vector3.right, ModelForwardAxis, YRotationLimits.y, radius / 1.2f); Handles.DrawWireArc(startLookLocal, Vector3.right, ModelForwardAxis, YRotationLimits.x, radius / 1.2f); if (StartLookElasticRangeY > 0f) { Handles.color = new Color(0.3f, 0.3f, 0.3f, 0.04f); Handles.DrawSolidArc(startLookLocal, Vector3.right, ModelForwardAxis, StartLookElasticRangeY, radius / 3.2f); Handles.DrawSolidArc(startLookLocal, Vector3.right, ModelForwardAxis, -StartLookElasticRangeY, radius / 3.2f); } if (XRotationLimits != _gizmosLastHorizClamp) { _gizmosHorizAlpha = 1.5f; } // Horizontal Handles.color = new Color(0.3f, 1f, 0.1f, 0.08f * Mathf.Min(_gizmosHorizAlpha, 1f)); Handles.DrawSolidArc(startLookLocal, ModelUpAxis, ModelForwardAxis, XRotationLimits.x, radius); Handles.DrawSolidArc(startLookLocal, ModelUpAxis, ModelForwardAxis, XRotationLimits.y, radius); Handles.color = new Color(0.22f, .8f, 0.08f, 0.75f); Handles.DrawWireArc(startLookLocal, ModelUpAxis, ModelForwardAxis, XRotationLimits.x, radius); Handles.DrawWireArc(startLookLocal, ModelUpAxis, ModelForwardAxis, XRotationLimits.y, radius); if (StartLookElasticRangeX > 0f) { Handles.color = new Color(0.3f, 0.3f, 0.3f, 0.04f); Handles.DrawSolidArc(startLookLocal, ModelUpAxis, ModelForwardAxis, StartLookElasticRangeX, radius / 3.2f); Handles.DrawSolidArc(startLookLocal, ModelUpAxis, ModelForwardAxis, -StartLookElasticRangeX, radius / 3.2f); } if (LookState == EFHeadLookState.ClampedAngle) { Handles.color = new Color(1f, 1f, 0.1f, 0.7f); } else { Handles.color = new Color(0.3f, 1f, 0.7f, 0.7f); } axisDir = BaseTransform.InverseTransformDirection(dir); axisDir.x = 0; axisDir.z = Mathf.Abs(axisDir.z); axisDir.Normalize(); Handles.DrawLine(startLookLocal, startLookLocal + axisDir * radius / 1.2f); _gizmosLastHorizClamp = XRotationLimits; _gizmosLastVertClamp = YRotationLimits; _gizmosVertAlpha -= 0.03f; _gizmosHorizAlpha -= 0.03f; Handles.matrix = Matrix4x4.identity; }
//Vector3 firstBoneOff = Vector3.zero; public void Init() { if (SpineBones.Count == 0) { if (SpineTransforms.Count > 2) { CreateSpineChain(SpineTransforms[0], SpineTransforms[SpineTransforms.Count - 1]); Debug.Log("[SPINE ANIMATOR] Auto Bone Conversion from old version of Spine Animator! Please select your objects with Spine Animator to pre-convert it instead of automatically doing it when game Starts! (" + name + ")"); } else { Debug.Log("[SPINE ANIMATOR] could not initialize Spine Animator inside '" + name + "' because there are no bones to animate!"); return; } } if (initialized) { Debug.Log("[Spine Animator] " + name + " is already initialized!"); return; } if (BaseTransform == null) { BaseTransform = FindBaseTransform(); } // Checking bones for zero-distance ones for (int i = 0; i < SpineBones.Count; i++) { Vector3 childPos; if (i == SpineBones.Count - 1) { childPos = SpineBones[i - 1].transform.position + (SpineBones[i - 1].transform.position - SpineBones[i].transform.position); } else { childPos = SpineBones[i + 1].transform.position; } float dist = Vector3.Distance(SpineBones[i].transform.position, childPos); if (dist < 0.01f) { float refDistance = (SpineBones[SpineBones.Count - 1].transform.position - SpineBones[SpineBones.Count - 2].transform.parent.position).magnitude; Vector3 forw = SpineBones[i].transform.position - BaseTransform.position; Vector3 loc = BaseTransform.InverseTransformDirection(forw); loc.y = 0f; loc.Normalize(); SpineBones[i + 1].DefaultForward = loc; // firstBoneOff SpineBones[i + 1].transform.position = SpineBones[i + 1].transform.position + BaseTransform.TransformDirection(loc) * refDistance * -0.125f; } } referenceDistance = 0f; // Preparing bones for (int i = 0; i < SpineBones.Count; i++) { SpineBones[i].PrepareBone(BaseTransform, SpineBones, i); referenceDistance += SpineBones[i].BoneLength; } referenceDistance /= (float)(SpineBones.Count); frontHead = new HeadBone(SpineBones[0].transform); frontHead.PrepareBone(BaseTransform, SpineBones, 0); backHead = new HeadBone(SpineBones[SpineBones.Count - 1].transform); backHead.PrepareBone(BaseTransform, SpineBones, SpineBones.Count - 1); // Collision calculations helper list CollidersDataToCheck = new List <FImp_ColliderData_Base>(); // Straightening spine pose to desired positions and rotations on init chainReverseFlag = !LastBoneLeading; UpdateChainIndexHelperVariables(); ReposeSpine(); //SpineMotion(); initialized = true; }