Пример #1
0
        public override void TryExitState(float DeltaTime)
        {
            var scaleFactor = animal.ScaleFactor;
            var Radius      = animal.RayCastRadius * scaleFactor;

            DeltaGoingDown = GoingDown;
            var Gravity = animal.Gravity;

            GoingDown = Vector3.Dot(animal.DeltaPos, Gravity) > 0; //Check if is falling down


            //GoingDown = Vector3.Dot(animal.DeltaPos, Gravity) > 0; //Check if is falling down
            float DeltaDistance = 0;

            if (GoingDown)
            {
                DeltaDistance        = Vector3.Project(animal.DeltaPos, Gravity).magnitude;
                FallCurrentDistance += DeltaDistance;
            }

            FallPoint = animal.Main_Pivot_Point;
            //FallPoint += Vector3.Project(animal.AdditivePosition, Gravity); //To check ahead that the animal can land..

            if (animal.debugGizmos && debug)
            {
                MTools.DrawWireSphere(FallPoint, Color.magenta, Radius);
                MTools.DrawWireSphere(FallPoint + Gravity * animal.Height, (Color.red + Color.blue) / 2, Radius);
                Debug.DrawRay(FallPoint, Gravity * 100f, Color.magenta);
            }

            if (Physics.Raycast(FallPoint, Gravity, out FallRayCast, 100f, animal.GroundLayer, IgnoreTrigger))
            {
                DistanceToGround = FallRayCast.distance;

                FoundLand = true;

                if (animal.debugGizmos && debug)
                {
                    MTools.DrawWireSphere(FallRayCast.point, (Color.blue + Color.red) / 2, Radius);
                    MTools.DrawWireSphere(FallPoint, (Color.red), Radius);
                }

                switch (BlendFall)
                {
                case FallBlending.DistanceNormalized:
                {
                    var realDistance = DistanceToGround - animal.Height;
                    if (MaxHeight < realDistance)
                    {
                        MaxHeight = realDistance;         //get the Highest Distance the first time you touch the ground
                    }
                    else
                    {
                        realDistance -= LowerBlendDistance;

                        FallBlend = Mathf.Lerp(FallBlend, realDistance / MaxHeight, DeltaTime * 10); //Small blend in case there's a new ground found
                        animal.State_SetFloat(1 - FallBlend);                                        //Blend between High and Low Fall
                    }
                }
                break;

                case FallBlending.Distance:
                    animal.State_SetFloat(FallCurrentDistance);
                    break;

                case FallBlending.VerticalVelocity:
                    var UpInertia = Vector3.Project(animal.DeltaPos, animal.UpVector).magnitude;       //Clean the Vector from Forward and Horizontal Influence
                    animal.State_SetFloat(UpInertia / animal.DeltaTime * (GoingDown ? 1 : -1));
                    break;

                default:
                    break;
                }



                if (animal.Height > DistanceToGround || ((DistanceToGround - DeltaDistance) < 0)) //Means has touched the ground
                {
                    var angl      = Vector3.Angle(FallRayCast.normal, animal.UpVector);
                    var DeepSlope = angl > animal.maxAngleSlope;


                    if (!DeepSlope) //Check if we are not on a deep slope
                    {
                        AllowExit();
                        animal.Grounded   = true;
                        animal.UseGravity = false;
                        var GroundedPos = Vector3.Project(FallRayCast.point - animal.transform.position, Gravity); //IMPORTANT HACk FOR

                        animal.Teleport_Internal(animal.transform.position + GroundedPos);                         //SUPER IMPORTANT!!!
                        animal.ResetUPVector();                                                                    //IMPORTAAANT!

                        UpImpulse = Vector3.zero;
                        Debugging($"[Try Exit] (Grounded) + [Terrain Angle ={angl}]");
                    }
                }
            }
            else
            {
                //Means that has lost the RayCastHit that it had
                if (FoundLand)
                {
                    // Debug.LogWarning("The Animal Tried to go below the terrain.... Unity Physic Bug  :( ");
                    animal.Teleport_Internal(animal.LastPos); //HACK WHEN THE ANIMAL Goes UnderGround
                    animal.ResetUPVector();
                }
            }

            if (!animal.Zone && !animal.HasExternalForce)
            {
                if ((DeltaGoingDown && !GoingDown))
                {
                    if (LastDeltaDistance > DeltaDistance && DeltaDistance != 0)
                    {
                        //Means that is still trying to fall but it cant because something is bloking the fall soo lets push it forward
                        animal.ResetUPVector();
                        animal.GravityTime          = animal.StartGravityTime;
                        animal.MovementAxis.z       = 1; //Force going forward HACK
                        animal.InertiaPositionSpeed = animal.Forward * animal.ScaleFactor * DeltaTime * animal.FallForward;
                        Debug.Log("GoingForward " + DeltaDistance);
                    }
                }
            }

            LastDeltaDistance = DeltaDistance;
        }
Пример #2
0
        public override void TryExitState(float DeltaTime)
        {
            var scaleFactor = animal.ScaleFactor;
            var Radius      = animal.RayCastRadius * scaleFactor;

            var Gravity = animal.Gravity;

            bool GoingDown = Vector3.Dot(animal.DeltaPos, Gravity) > 0; //Check if is falling down

            var DeltaDistance_Down = Vector3.Project(animal.DeltaPos, Gravity).magnitude;

            if (GoingDown)
            {
                FallCurrentDistance += DeltaDistance_Down;
            }

            FallPoint = animal.Main_Pivot_Point;
            //FallPoint += Vector3.Project(animal.AdditivePosition, Gravity); //To check ahead that the animal can land..

            if (animal.debugGizmos && debug)
            {
                MTools.DrawWireSphere(FallPoint, Color.magenta, Radius);
                MTools.DrawWireSphere(FallPoint + Gravity * animal.Height, (Color.red + Color.blue) / 2, Radius);
                Debug.DrawRay(FallPoint, Gravity * 100f, Color.magenta);
            }

            if (Physics.Raycast(FallPoint, Gravity, out FallRayCast, 100f, animal.GroundLayer, QueryTriggerInteraction.Ignore))
            {
                DistanceToGround = FallRayCast.distance;

                if (animal.debugGizmos && debug)
                {
                    MTools.DrawWireSphere(FallRayCast.point, (Color.blue + Color.red) / 2, Radius);
                    MTools.DrawWireSphere(FallPoint, (Color.red), Radius);
                }

                switch (BlendFall)
                {
                case FallBlending.DistanceNormalized:
                {
                    var realDistance = DistanceToGround - animal.Height;
                    if (MaxHeight < realDistance)
                    {
                        MaxHeight = realDistance;         //get the Highest Distance the first time you touch the ground
                    }
                    else
                    {
                        realDistance -= LowerBlendDistance;

                        FallBlend = Mathf.Lerp(FallBlend, realDistance / MaxHeight, DeltaTime * 10); //Small blend in case there's a new ground found
                        animal.State_SetFloat(1 - FallBlend);                                        //Blend between High and Low Fall
                    }
                }
                break;

                case FallBlending.Distance:
                    animal.State_SetFloat(FallCurrentDistance);
                    break;

                case FallBlending.VerticalVelocity:
                    var UpInertia = Vector3.Project(animal.DeltaPos, animal.UpVector).magnitude;       //Clean the Vector from Forward and Horizontal Influence
                    animal.State_SetFloat(UpInertia / animal.DeltaTime * (GoingDown ? 1 : -1));
                    break;

                default:
                    break;
                }



                if (animal.IsOnZone && animal.HasExternalForce)
                {
                    return;                                             //HACK FOR SPRING AND WIND ZONES
                }
                //  Debug.Log($"Dist: {DistanceToGround:F3}  |  Delta_Dist: {DeltaDistance_Down:F3}  |  {(DistanceToGround - DeltaDistance_Down):F3}");
                if (animal.Height > DistanceToGround || ((DistanceToGround - DeltaDistance_Down) < 0)) //Means has touched the ground
                {
                    var angl      = Vector3.Angle(FallRayCast.normal, animal.UpVector);
                    var DeepSlope = angl > animal.maxAngleSlope;



                    if (!DeepSlope)
                    {
                        AllowExit();
                        animal.Grounded   = true;
                        animal.UseGravity = false;
                        var GroundedPos = Vector3.Project(FallRayCast.point - animal.transform.position, Gravity); //IMPORTANT

                        animal.Teleport(animal.transform.position + GroundedPos);                                  //SUPER IMPORTANT!!!
                        animal.ResetUPVector();                                                                    //IMPORTAAANT!

                        UpImpulse = Vector3.zero;
                        Debugging("[Try Exit] (Grounded) + [Terrain Angle = " + angl + "]");
                    }
                }
            }
        }
Пример #3
0
        private bool TryFallRayCasting(Vector3 fall_Pivot, float Multiplier)
        {
            FallHits = new RaycastHit[RayHits];

            var Direction = animal.TerrainSlope < 0 ? animal.Gravity : -transform.up;

            var Radius = animal.RayCastRadius * animal.ScaleFactor;

            Hits = Physics.SphereCastNonAlloc(fall_Pivot, Radius, Direction, FallHits, Multiplier, animal.GroundLayer, IgnoreTrigger);

            if (Hits > 0)
            {
                if (animal.Grounded)
                {
                    foreach (var hit in FallHits)
                    {
                        if (hit.collider != null)
                        {
                            var slope = Vector3.Angle(hit.normal, animal.UpVector);
                            slope *= Vector3.Dot(animal.UpVector, animal.Forward) < 0 ? -1 : 1;            //Calcualte the Fall Angle Positive or Negative

                            if (slope > -animal.maxAngleSlope && slope <= animal.maxAngleSlope)
                            {
                                FallRayCast = hit;

                                if (debug)
                                {
                                    Debug.DrawRay(fall_Pivot, Direction * Multiplier, Color.magenta);
                                    Debug.DrawRay(FallRayCast.point, FallRayCast.normal * animal.ScaleFactor * 0.2f, Color.magenta);
                                    MTools.DrawWireSphere(fall_Pivot + Direction * DistanceToGround, Color.magenta, Radius);
                                }
                                break;
                            }
                        }
                    }

                    DistanceToGround = FallRayCast.distance;

                    var TerrainSlope = Vector3.Angle(FallRayCast.normal, animal.UpVector);
                    TerrainSlope *= Vector3.Dot(animal.UpVector, animal.Forward) < 0 ? -1 : 1;            //Calcualte the Fall Angle Positive or Negative

                    if (TerrainSlope < -animal.maxAngleSlope || animal.DeepSlope)
                    {
                        Debugging($"[Try] Slope is too deep [{FallRayCast.collider}] | Hits: {Hits} | Slope : {TerrainSlope:F2} T:{Time.time:F3}");
                        return(true);
                    }
                }
                else   //If the Animal is in the air  NOT GROUNDED
                {
                    FallRayCast      = FallHits[0];
                    DistanceToGround = FallRayCast.distance;

                    var FallSlope = Vector3.Angle(FallRayCast.normal, animal.UpVector);

                    if (FallSlope > animal.maxAngleSlope)
                    {
                        Debugging($"[Try] The Animal is on the Air and the angle SLOPE of the ground Hitted is too Deep");

                        return(true);
                    }
                    if (animal.Height >= DistanceToGround)  //If the distance to ground is very small means that we are very close to the ground
                    {
                        if (animal.ExternalForce != Vector3.zero)
                        {
                            return(true);                                      //Hack for external forces
                        }
                        Debugging($"[Try Failed] Distance to the ground is very small means that we are very close to the ground. CHECK IF GROUNDED");
                        animal.CheckIfGrounded();//Hack IMPORTANT HACK!!!!!!!
                        return(false);
                    }
                }
            }
            else
            {
                Debugging($"[Try] There's no Ground beneath the Animal");
                //    Debug.Break();
                return(true);
            }

            //  animal.CheckIfGrounded(); //Hack IMPORTANT HACK!!!!!!!

            return(false);
        }
Пример #4
0
        /// <summary>Raycasting stuff to align and calculate the ground from the animal ****IMPORTANT***</summary>
        internal virtual void AlignRayCasting()
        {
            MainRay            = FrontRay = false;
            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

            //var Direction = Gravity;
            var Direction = -transform.up;



            if (Physics.Raycast(Main_Pivot_Point, Direction, out hit_Chest, Pivot_Multiplier, GroundLayer, QueryTriggerInteraction.Ignore))
            {
                FrontRay = true;

                var MainPivotSlope = Vector3.SignedAngle(hit_Chest.normal, UpVector, Right);


                if (MainPivotSlope > maxAngleSlope)  //Means that the Slope is higher thanthe Max slope so stop the animal from Going forward AND ONLY ON LOCOMOTION
                {
                    if (MovementAxisRaw.z > 0 && !hit_Chest.transform.gameObject.CompareTag("Stair"))
                    {
                        AdditivePosition = Vector3.ProjectOnPlane(AdditivePosition, Forward); //Remove Forward Movement
                        MovementAxis.z   = 0;
                    }
                }

                //    else
                {
                    if (debugGizmos)
                    {
                        Debug.DrawRay(hit_Chest.point, hit_Chest.normal * ScaleFactor * 0.2f, Color.green);
                        MTools.DrawWireSphere(Main_Pivot_Point + Direction * (hit_Chest.distance - RayCastRadius), 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;
                    }

                    hit_Chest.collider.attachedRigidbody?.AddForceAtPosition(Gravity * (RB.mass / 2), hit_Chest.point, ForceMode.Force);
                }
            }
            else
            {
                platform = null;
            }

            if (Has_Pivot_Hip && Has_Pivot_Chest) //Ray From the Hip to the ground
            {
                var hipPoint = Pivot_Hip.World(transform) + DeltaVelocity;

                if (Physics.Raycast(hipPoint, Direction, out hit_Hip, ScaleFactor * Pivot_Hip.multiplier, GroundLayer, QueryTriggerInteraction.Ignore))
                {
                    MainRay = true;

                    if (debugGizmos)
                    {
                        Debug.DrawRay(hit_Hip.point, hit_Hip.normal * ScaleFactor * 0.2f, Color.green);
                        MTools.DrawWireSphere(hipPoint + Direction * (hit_Hip.distance - RayCastRadius), Color.green, RayCastRadius * ScaleFactor);
                    }

                    if (platform == null || platform != hit_Chest.transform)                 //Platforming logic
                    {
                        platform     = hit_Hip.transform;
                        platform_Pos = platform.position;
                        platform_Rot = platform.rotation;
                    }

                    hit_Hip.collider.attachedRigidbody?.AddForceAtPosition(Gravity * (RB.mass / 2), hit_Hip.point, ForceMode.Force);

                    if (!FrontRay)
                    {
                        hit_Chest = hit_Hip;            //If there's no Front Ray
                    }
                }
                else
                {
                    platform = null;

                    if (FrontRay)
                    {
                        InertiaPositionSpeed = Forward * ScaleFactor * DeltaTime * 2; //Force going forward in case there's no front Ray (HACK)
                        hit_Hip = hit_Chest;                                          //In case there's no Hip Ray
                    }
                }
            }
            else
            {
                MainRay = FrontRay;  //Just in case you dont have HIP RAY IMPORTANT FOR HUMANOID CHARACTERSSSSSSSSSSSS
                hit_Hip = hit_Chest; //In case there's no Hip Ray
            }

            if (ground_Changes_Gravity)
            {
                Gravity = -hit_Hip.normal;
            }

            CalculateSurfaceNormal();
        }