//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);
        }
    }