Пример #1
0
        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;
                    }
                }
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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();
        }