public override void TryExitState(float DeltaTime) { var scaleFactor = animal.ScaleFactor; var Radius = animal.RayCastRadius * scaleFactor; bool GoingDown = Vector3.Dot(animal.DeltaPos, animal.GravityDirection) > 0; //Check if is falling down if (GoingDown) { FallCurrentDistance += Vector3.Project(animal.DeltaPos, animal.GravityDirection).magnitude; } FallPoint = animal.Main_Pivot_Point + Vector3.ProjectOnPlane(animal.DeltaPos, animal.UpVector) + (animal.GravityDirection * Radius); if (animal.debugGizmos && debug) { MalbersTools.DebugWireSphere(FallPoint, Color.magenta, Radius); MalbersTools.DebugWireSphere(FallPoint + animal.GravityDirection * animal.Height, Color.red, Radius); Debug.DrawRay(FallPoint, animal.GravityDirection * 100f, Color.magenta); } //int hits = Physics.SphereCastNonAlloc(FallPoint, animal.RayCastRadius * animal.ScaleFactor,animal.GravityDirection, FallHits, 100f, animal.GroundLayer, QueryTriggerInteraction.Ignore); //if (hits > 0) if (Physics.SphereCast(FallPoint, Radius, animal.GravityDirection, out FallRayCast, 100f, animal.GroundLayer, QueryTriggerInteraction.Ignore)) { DistanceToGround = FallRayCast.distance;// - (/*animal.AdditivePosition.magnitude +*/ animal.DeltaPos.magnitude); if (animal.debugGizmos && debug) { MalbersTools.DebugWireSphere(FallPoint + animal.GravityDirection * DistanceToGround, Color.magenta, Radius); } switch (BlendFall) { case FallBlending.DistanceNormalized: { if (MaxHeight < DistanceToGround) { MaxHeight = DistanceToGround; //get the Highest Distance the first time you touch the ground } FallBlend = Mathf.Lerp(FallBlend, (DistanceToGround - LowerBlendDistance) / (MaxHeight - LowerBlendDistance), DeltaTime * 20); //Small blend in case there's a new ground found animal.SetFloatID(FallBlend); //Blend between High and Low Fall } break; case FallBlending.Distance: animal.SetFloatID(FallCurrentDistance); break; case FallBlending.VerticalVelocity: var UpInertia = MalbersTools.CleanUpVector(animal.DeltaPos, animal.Forward, animal.Right).magnitude; //Clean the Vector from Forward and Horizontal Influence animal.SetFloatID(UpInertia / animal.DeltaTime * (GoingDown?1:-1)); break; default: break; } // Debug.Log(animal.Height + ">=" + DistanceToGround); if (animal.Height >= DistanceToGround) { var DeepSlope = Vector3.Angle(FallRayCast.normal, animal.UpVector) > animal.maxAngleSlope; if (!DeepSlope) { animal.AlingRayCasting(); //Check one time the Align Rays to calculate the Angle Slope used on the CanFallOnSlope AllowExit(); animal.Grounded = true; //This Allow Locomotion and Idle to Try Activate themselves animal.UseGravity = false; } } } }
private bool TryFallSphereCastNonAlloc(Vector3 fall_Pivot, float Multiplier) { var Radius = animal.RayCastRadius * animal.ScaleFactor; fallHits = Physics.SphereCastNonAlloc(fall_Pivot, Radius, -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); Debug.DrawRay(FallRayCast.point, FallRayCast.normal * animal.ScaleFactor * 0.3f, Color.magenta); MalbersTools.DebugWireSphere(fall_Pivot + -transform.up * DistanceToGround, Color.magenta, Radius); } if (!animal.Grounded) //If the Animal is in the air { 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>Raycasting stuff to align and calculate the ground from the animal ****IMPORTANT***</summary> internal virtual void AlingRayCasting() { Height = (height) * ScaleFactor; //multiply the Height by the scale TO properly ALign with the terrain we need to remove the Radius // var LastHitChest = hit_Chest; //Save the last Hit chest hit_Chest = new RaycastHit(); //Clean the Raycasts every time hit_Hip = new RaycastHit(); //Clean the Raycasts every time hit_Chest.distance = hit_Hip.distance = Height; //Reset the Distances to the Heigth of the animal if (Physics.SphereCast(Main_Pivot_Point, RayCastRadius * ScaleFactor, -transform.up, out hit_Chest, Pivot_Multiplier, GroundLayer, QueryTriggerInteraction.Ignore)) //if (Physics.Raycast(Main_Pivot_Point, -_transform.up, out hit_Chest, Pivot_Multiplier, GroundLayer, QueryTriggerInteraction.Ignore)) { FrontRay = true; MainPivotSlope = Vector3.Angle(hit_Chest.normal, UpVector); MainPivotSlope *= Vector3.Dot(Forward_no_Y, hit_Chest.normal) > 0 ? -1 : 1; //if (MainPivotSlope > maxAngleSlope && ActiveStateID.ID == 1 ) //Means that the Slope is higher thanthe Max slope so stop the animal from Going forward AND ONLY ON LOCOMOTION //{ // if (!hit_Chest.transform.CompareTag("Stair")) // { // AdditivePosition = Vector3.ProjectOnPlane(AdditivePosition, Forward); // MovementAxis.z = Mathf.MoveTowards(MovementAxis.z, 0, DeltaTime); // } //} if (debugGizmos) { Debug.DrawRay(hit_Chest.point + AdditivePosition, hit_Chest.normal * ScaleFactor * 0.2f, Color.green); MalbersTools.DebugWireSphere(Main_Pivot_Point + AdditivePosition + -transform.up * hit_Chest.distance, Color.green, RayCastRadius * ScaleFactor); } if (platform == null || platform != hit_Chest.transform) //Platforming logic { platform = hit_Chest.transform; platform_Pos = platform.position; platform_Rot = platform.rotation; } } else { platform = null; FrontRay = false; hit_Chest = hit_Hip; } if (Has_Pivot_Hip && Has_Pivot_Chest) //Ray From the Hip to the ground { var hipPoint = Pivot_Hip.World(transform); // if (Physics.Raycast(hipPoint, -_transform.up, out hit_Hip, ScaleFactor * Pivot_Hip.multiplier, GroundLayer, QueryTriggerInteraction.Ignore)) if (Physics.SphereCast(hipPoint, RayCastRadius * ScaleFactor, -transform.up, out hit_Hip, ScaleFactor * Pivot_Hip.multiplier, GroundLayer, QueryTriggerInteraction.Ignore)) { MainRay = true; if (debugGizmos) { Debug.DrawRay(hit_Hip.point + AdditivePosition, hit_Hip.normal * ScaleFactor * 0.2f, Color.green); MalbersTools.DebugWireSphere(hipPoint + AdditivePosition + -transform.up * hit_Hip.distance, Color.green, RayCastRadius * ScaleFactor); } if (platform == null || platform != hit_Hip.transform) //Platforming logic { platform = hit_Hip.transform; platform_Pos = platform.position; platform_Rot = platform.rotation; } } else { platform = null; MainRay = false; } } if (!Has_Pivot_Hip || !MainRay) { hit_Hip = hit_Chest; //In case there's no Hip Ray } if (ground_Changes_Gravity) { GravityDirection = -hit_Hip.normal; } CalculateSurfaceNormal(); }