/// <summary>─Get jumping on a cliff</summary> void Can_Jump_on_Cliff(float normalizedTime) { if (normalizedTime >= Cliff.minValue && normalizedTime <= Cliff.maxValue) { if (Physics.Raycast(animal.Main_Pivot_Point, -transform.up, out JumpRay, CliffRay * animal.ScaleFactor, animal.GroundLayer)) { if (Vector3.Angle(JumpRay.normal, Vector3.up) < animal.maxAngleSlope) //Jump to a jumpable cliff not an inclined one { if (animal.debug) { Debug.DrawLine(animal.Main_Pivot_Point, JumpRay.point, Color.black); MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.black); } animal.SetIntID(110); } } else { if (animal.debug) { Debug.DrawRay(animal.Main_Pivot_Point, -transform.up * CliffRay * animal.ScaleFactor, Color.black); MalbersTools.DebugPlane(animal.Main_Pivot_Point - (transform.up * CliffRay * animal.ScaleFactor), 0.1f, Color.black); } } } }
private bool TryFallSphereCastNonAlloc(Vector3 fall_Pivot, float Multiplier) { fallHits = Physics.SphereCastNonAlloc(fall_Pivot, animal.RayCastRadius * animal.ScaleFactor, -transform.up, FallHits, Multiplier, animal.GroundLayer, QueryTriggerInteraction.Ignore); if (fallHits > 0) { FallRayCast = FallHits[0]; DistanceToGround = FallRayCast.distance; if (debug) { Debug.DrawRay(fall_Pivot, -transform.up * Multiplier, Color.magenta); MalbersTools.DebugPlane(FallRayCast.point, animal.RayCastRadius * animal.ScaleFactor, Color.magenta, true); } if (!animal.Grounded) { var TerrainSlope = Vector3.Angle(FallRayCast.normal, animal.UpVector); var DeepSlope = TerrainSlope > animal.maxAngleSlope; if (DeepSlope) { if (debug && animal.debugStates) { Debug.Log("Try <B>Fall</B> State: The Animal is on Air but angle SLOPE of the ground found is too Deep"); } return(true); } } else if (animal.Grounded && animal.DeepSlope) //if wefound something but there's a deep slope { if (debug && animal.debugStates) { Debug.Log("Try <B>Fall</B> State: The Ground angle SLOPE is too Deep"); } return(true); } if (animal.Height >= DistanceToGround && !animal.Grounded) //If the distance to ground is very small means that we are very close to the ground { if (debug && animal.debugStates) { Debug.Log("Try <B>Fall</B> State: The distance to ground is very small means that we are very close to the ground.// Ground = true"); } // animal.Grounded = true; //This Allow Locomotion and Idle to Try Activate themselves return(false); } } else { if (debug && animal.debugStates) { Debug.Log("Try <B>Fall</B>: There's no Ground beneath the Animal"); } return(true); } return(false); }
/// <summary> /// Check if the animal can change to fall state if there's no future ground to land on /// </summary> /// <param name="normalizedTime"></param> void Can_Fall(float normalizedTime) { Debug.DrawRay(animal.Pivot_fall, -animal.transform.up * animal.Pivot_Multiplier * fallRay, Color.red); if (Physics.Raycast(animal.Pivot_fall, -animal.transform.up, out JumpRay, animal.Pivot_Multiplier * fallRay, animal.GroundLayer)) { if ((jumpPoint - JumpRay.point.y) <= (stepHeight * animal.ScaleFactor) && (Vector3.Angle(JumpRay.normal, Vector3.up) < animal.maxAngleSlope)) //If if finding a lower jump point; { animal.SetIntID(0); //Keep the INTID in 0 MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.red); } else { if (normalizedTime > willFall) { animal.SetIntID(111); //Set INTID to 111 to activate the FALL transition } MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.yellow); } } else { if (normalizedTime > willFall) { animal.SetIntID(111); //Set INTID to 111 to activate the FALL transition } MalbersTools.DebugPlane(animal.Pivot_fall - (animal.transform.up * animal.Pivot_Multiplier * fallRay), 0.1f, Color.red); } }
/// <summary>Check if the animal can change to fall state if there's no future ground to land on</summary> void Can_Fall(float normalizedTime) { Debug.DrawRay(animal.Pivot_fall, -transform.up * animal.Pivot_Multiplier * fallRay, Color.red); if (MinJumpLand > 0) { if (Physics.Raycast(animal.Pivot_fall, -transform.up, out JumpRay, animal.Pivot_Multiplier * fallRay, animal.GroundLayer)) { float distance = Vector3.Distance(animal.Pivot_fall, JumpRay.point); float Angle = Vector3.Angle(Vector3.up, JumpRay.normal); if (animal.debug) { Debug.Log("Min Distance to complete the Jump: " + distance); } if ((MinJumpLand * animal.ScaleFactor) < distance || Angle > animal.maxAngleSlope) { animal.SetIntID(111); MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.yellow); } } else { animal.SetIntID(111); } } else if (Physics.Raycast(animal.Pivot_fall, -transform.up, out JumpRay, animal.Pivot_Multiplier * fallRay, animal.GroundLayer)) { if ((jumpPoint - JumpRay.point.y) <= (stepHeight * animal.ScaleFactor) && (Vector3.Angle(JumpRay.normal, Vector3.up) < animal.maxAngleSlope)) //If if finding a lower jump point; { MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.red); } else { animal.SetIntID(111); //Set INTID to 111 to activate the FALL transition MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.yellow); } } else { animal.SetIntID(111); //Set INTID to 111 to activate the FALL transition MalbersTools.DebugPlane(animal.Pivot_fall - (transform.up * animal.Pivot_Multiplier * fallRay), 0.1f, Color.red); } }
///────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── /// <summary> Fall Logic </summary> protected virtual void Falling() { // fall_Point = Chest_Pivot_Point; // if (!Fly) fall_Point = Main_Pivot_Point + (T_Forward * (Shift ? GroundSpeed + 1 : GroundSpeed) * FallRayDistance * ScaleFactor); //Calculate ahead the falling ray if (FrameCounter % FallRayInterval != 0) { return; //Skip to reduce aditional raycasting } //Don't Calcultate Fall Ray if the animal on any of these states if (AnimState == AnimTag.Sleep || AnimState == AnimTag.Action || AnimState == AnimTag.Swim || AnimState == AnimTag.Idle || swim == true || underwater) { return; } float Multiplier = Pivot_Multiplier; if (AnimState == AnimTag.Jump || AnimState == AnimTag.Fall || AnimState == AnimTag.Fly) { Multiplier *= FallRayMultiplier; } //Set the Fall Ray a bit farther from the front feet. if (Physics.Raycast(fall_Point, -T_Up, out FallRayCast, Multiplier, GroundLayer)) { if (debug) { Debug.DrawRay(fall_Point, -T_Up * Multiplier, Color.magenta); MalbersTools.DebugPlane(FallRayCast.point, 0.1f, Color.magenta, true); } float fallSlopeAngle = Vector3.Angle(FallRayCast.normal, Vector3.up); fallSlopeAngle *= Vector3.Dot(T_ForwardNoY, FallRayCast.normal) > 0 ? 1 : -1; //Calcualte the Fall Angle Positive or Negative if ((fallSlopeAngle > maxAngleSlope) || (!frontray && !backray)) //found something but there's no BACK/FrontRay { fall = true; return; } fall = false; CheckForLanding(); if (AnimState == AnimTag.SwimJump) { Swim = false; //in case is jumping from the water to the ground ***Important } } else { fall = true; FallRayCast.normal = UpVector; //if there's no fall ray Reset the Fall Normal to the Horizontal Terrain if (debug) { MalbersTools.DebugPlane(fall_Point + (-T_Up * Multiplier), 0.1f, Color.gray, true); Debug.DrawRay(fall_Point, -T_Up * Multiplier, Color.gray); } } }
// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { bool isInTransition = animator.IsInTransition(layerIndex); if (!isInTransition && JumpMultiplier > 0 && animal.JumpHeightMultiplier > 0) //Add More Height to the Jump { rb.AddForce((Vector3.up * JumpMultiplier * 10) + (animator.transform.forward * ForwardMultiplier * 10), ForceMode.Acceleration); } Debug.DrawRay(animal.Pivot_fall, -animal.transform.up * animal.Chest_Pivot_Multiplier * fallRay, Color.red); //This code is execute when the animal can change to fall state if there's no future ground to land on if (Physics.Raycast(animal.Pivot_fall, -animal.transform.up, out JumpRay, animal.Chest_Pivot_Multiplier * fallRay, animal.GroundLayer)) { if ((jumpPoint - JumpRay.point.y) <= (threshold * animal.ScaleFactor) && (Vector3.Angle(JumpRay.normal, Vector3.up) < animal.maxAngleSlope)) //If if finding a lower jump point; { animal.SetIntID(0); //Keep the INTID in 0 MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.red); } else { if (stateInfo.normalizedTime > willFall) { animal.SetIntID(111); //Set INTID to 111 to activate the FALL transition } MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.yellow); } } else { if (stateInfo.normalizedTime > willFall) { animal.SetIntID(111); //Set INTID to 111 to activate the FALL transition } MalbersTools.DebugPlane(animal.Pivot_fall - (animal.transform.up * animal.Chest_Pivot_Multiplier * fallRay), 0.1f, Color.red); } //───────────────────────────────────────────────Get jumping on a cliff ──────────────────────────────────────────────────────────────────────────────────────────────────── if (stateInfo.normalizedTime >= startEdge && stateInfo.normalizedTime <= finishEdge) { if (Physics.Raycast(animal.Chest_Pivot_Point, -animal.transform.up, out JumpRay, CliffRay * animal.ScaleFactor, animal.GroundLayer)) { if (Vector3.Angle(JumpRay.normal, Vector3.up) < animal.maxAngleSlope) //Jump to a jumpable cliff not an inclined one { if (animal.debug) { Debug.DrawLine(animal.Chest_Pivot_Point, JumpRay.point, Color.black); MalbersTools.DebugTriangle(JumpRay.point, 0.1f, Color.black); } animal.SetIntID(110); } } else { if (animal.debug) { Debug.DrawRay(animal.Chest_Pivot_Point, -animator.transform.up * CliffRay * animal.ScaleFactor, Color.black); MalbersTools.DebugPlane(animal.Chest_Pivot_Point - (animal.transform.up * CliffRay * animal.ScaleFactor), 0.1f, Color.black); } } } if (animal.forwardJumpControl) //If the jump can be controlled on air { Vector3 pos = animator.transform.position; JumpControl = Vector3.Lerp(pos, pos - new Vector3(animator.velocity.x, 0, animator.velocity.z), Time.deltaTime); if (animal.MovementReleased) { animator.transform.position = Vector3.Lerp(animator.transform.position, JumpControl, smooth); } smooth += (animal.MovementReleased ? Time.deltaTime : -Time.deltaTime) * animal.smoothJumpForward; smooth = Mathf.Clamp01(smooth); } #region if is transitioning to flying //If the next animation is FLY smoothly remove the Y rigidbody speed if (rb && isInTransition && animator.GetNextAnimatorStateInfo(layerIndex).tagHash == Hash.Fly) { float transitionTime = animator.GetAnimatorTransitionInfo(layerIndex).normalizedTime; Vector3 cleanY = rb.velocity; if (Rb_Y_Speed < cleanY.y) { Rb_Y_Speed = cleanY.y; //Get the max Y SPEED } cleanY.y = Mathf.Lerp(Rb_Y_Speed, 0, transitionTime); rb.velocity = cleanY; } #endregion }
///────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── /// <summary> /// Fall Logic /// </summary> protected virtual void Falling() { //Don't Calcultate Fall Ray if the animal on any of these states if (CurrentAnimation(Hash.Tag_Sleep, Hash.Action, Hash.Swim)) { return; } float Multiplier = Chest_Pivot_Multiplier; RaycastHit hitpos; if (CurrentAnimation(Hash.Tag_Jump, Hash.Fall)) //If the animal is falling or jumping add the fall multiplier { Multiplier *= FallRayMultiplier; } //Set the Fall Ray a bit farther from the front feet. fall_Point = Chest_Pivot_Point; if (!Fly) { fall_Point += (transform.forward * (Shift ? GroundSpeed + 1 : GroundSpeed) * FallRayDistance * ScaleFactor); //Calculate ahead the falling ray } if (Physics.Raycast(fall_Point, -transform.up, out hitpos, Multiplier, GroundLayer)) //if (Physics.SphereCast(fall_Point,0.1f, -transform.up, out hitpos, Multiplier, GroundLayer)) { fall = false; if (debug) { Debug.DrawRay(fall_Point, -transform.up * Multiplier, Color.magenta); MalbersTools.DebugPlane(hitpos.point, 0.1f, Color.magenta, true); } if (Fly && land) { SetFly(false); //Reset Fly when the animal is near the ground IsInAir = false; groundSpeed = LastGroundSpeed; //Restore the GroundSpeed to the original } if (RealAnimatorState(Hash.Tag_SwimJump)) { Swim = false; //in case is jumping from the water to the ground ***Important } // float angle = Vector3.Angle(hitpos.normal, UpVector) * (transform.position.y <= hitpos.point.y ? 1 :-1); ////Debug.Log(angle); //if (angle < -maxAngleSlope) fall = true; //if the ground but is to Sloppy } else { fall = true; if (debug) { MalbersTools.DebugPlane(fall_Point + (-transform.up * Multiplier), 0.1f, Color.gray, true); Debug.DrawRay(fall_Point, -transform.up * Multiplier, Color.gray); } } }