//Loops over the gaits and selects the current one private void SelectGait() { //Gets the max distance //Debug.Log("Current player velocity : " + controller.localVelocityPlane); for (int i = 0; i < Gaits.Count; i++)//Loop { //Condition to select the gait ProceduralAnimationGaitStruct gait = Gaits[i]; Vector2 input = controller.localVelocityPlane / controller.speed; input.x = Mathf.Clamp(input.x * 1, -DistanceBetweenGaitPoints, DistanceBetweenGaitPoints); //Clamp and multiply (Multiplication is for responsivness) input.y = Mathf.Clamp(input.y * 1, -DistanceBetweenGaitPoints, DistanceBetweenGaitPoints); //Clamp and multiply (Multiplication is for responsivness) input = Vector2.ClampMagnitude(input, 1); float dist = 1 - (Vector2.Distance(input, gait.PlayerVelocity)); //Inverted and normalized distance CurrentGait = LerpGaits(CurrentGait, gait, dist); //Lineraly interpolates using the distance to 2D gait points } }
//Interpolates between two gaits private ProceduralAnimationGaitStruct LerpGaits(ProceduralAnimationGaitStruct a, ProceduralAnimationGaitStruct b, float t) { ProceduralAnimationGaitStruct outputGait = new ProceduralAnimationGaitStruct(); //Debug.Log("Interpolant is : " + t); //Interpolation outputGait.Name = a.Name; outputGait.FeetSpeed = Mathf.Lerp(a.FeetSpeed, b.FeetSpeed, t); outputGait.FeetHeightFactor = Mathf.Lerp(a.FeetHeightFactor, b.FeetHeightFactor, t); outputGait.FeetPosSmoothing = Mathf.Lerp(a.FeetPosSmoothing, b.FeetPosSmoothing, t); outputGait.RootBoneRotation = Vector3.Lerp(a.RootBoneRotation, b.RootBoneRotation, t); outputGait.LeftFootOriginOffset = Vector3.Lerp(a.LeftFootOriginOffset, b.LeftFootOriginOffset, t); outputGait.RightFootOriginOffset = Vector3.Lerp(a.RightFootOriginOffset, b.RightFootOriginOffset, t); outputGait.LeftFootPoleOffset = Vector3.Lerp(a.LeftFootPoleOffset, b.LeftFootPoleOffset, t); outputGait.RightFootPoleOffset = Vector3.Lerp(a.RightFootPoleOffset, b.RightFootPoleOffset, t); outputGait.LeftFootRotationOffset = Vector3.Lerp(a.LeftFootRotationOffset, b.LeftFootRotationOffset, t); outputGait.RightFootRotationOffset = Vector3.Lerp(a.RightFootRotationOffset, b.RightFootRotationOffset, t); if (t > 0.5f) { outputGait.Name = b.Name;//No interpolation with names } return(outputGait); }
// Start is called before the first frame update void Start() { CurrentGait = Gaits[0];//Set first gait to be the idle gait }
//All the logic for a single foot private void FootLogic(Transform RayOrigin, Transform FootPole, Transform FootTarget, ref Vector3 FootTargetPos, float HeightOffset, Vector3 FeetOriginOffset, Vector3 FeetPoleOffset, Vector3 FeetTargetRotationOffset, ProceduralAnimationGaitStruct Gait) { RayOrigin.localPosition = FeetOriginOffset; //Set new and updated local position for the current ray origin object FootPole.localPosition = FeetPoleOffset; //Pole offset in local Vector3 newFootTargetPos = FootTargetPos; //The new and updated foot target position if (Physics.Raycast(RayOrigin.position, Vector3.down * 10, out hit)) { Debug.DrawLine(RayOrigin.position, hit.point); newFootTargetPos.y = hit.point.y; //Reset Y axis pos if (HeightOffset > 0) //Move the feet target potition only when it is in air { newFootTargetPos = hit.point; //Set new foot target pos Vector3 distanceVector = FootTargetPos - newFootTargetPos; distanceVector.y = 0; if (distanceVector.sqrMagnitude > 0.01f) //Can we offset the feet in the Y axis or not ? { newFootTargetPos.y += HeightOffset; //Offset Y axis by the height value } } FootTargetPos = Vector3.Lerp(FootTargetPos, newFootTargetPos, Time.deltaTime * Gait.FeetPosSmoothing);//Set new left foot target pos with smoothing FootTarget.localRotation = Quaternion.Slerp(FootTarget.localRotation, Quaternion.Euler(FeetTargetRotationOffset), FeetRotationSmoothing * Time.deltaTime); } }