/// <summary>
        /// Performs ray with gameobject layer.
        /// </summary>
        /// <returns>If hit object and distance to objects</returns>
        public NewPoint PerformRays(Vector2 velocity, RayTypes rays, ref List <RaycastHit2D> raycastHits)
        {
            raycastHits.Clear();
            const float CompareZero    = 0.00001f;
            var         hitCollider    = false;
            Vector2     distanceToEdge = Vector2.zero;

            if (Mathf.Abs(velocity.x) > CompareZero)
            {
                var checkAxis = CheckCollisionAxis(velocity, AxisDirection.Horizontal, rays, layermask, ref raycastHits);
                if (checkAxis.HasPoint)
                {
                    hitCollider    = true;
                    distanceToEdge = checkAxis.Point;
                }
            }
            if (Mathf.Abs(velocity.y) > CompareZero)
            {
                var checkAxis = CheckCollisionAxis(velocity, AxisDirection.Vertical, rays, layermask, ref raycastHits);
                if (checkAxis.HasPoint)
                {
                    hitCollider     = true;
                    distanceToEdge += checkAxis.Point;
                }
            }

            if (hitCollider)
            {
                return(new NewPoint(distanceToEdge));
            }
            else
            {
                return(new NewPoint(false));
            }
        }
        private NewPoint CheckCollisionAxis(Vector2 velocity, AxisDirection axisDirection, RayTypes rayTypes, LayerMask layerMask, ref List <RaycastHit2D> raycastHits)
        {
            // percentage of the way to the edge where the ray should shoot
            const float DistanceToEdgeMultiplier = 0.75f;

            // If Vertical
            float   axisVelocity    = velocity.y;
            Vector2 direction       = new Vector2(0, axisVelocity);
            float   forwardDistance = objectExtents.y;
            float   sideDistance    = objectExtents.x * DistanceToEdgeMultiplier;
            Vector2 directionToEdge = Vector2.right;

            // If Horizontal
            if (axisDirection == AxisDirection.Horizontal)
            {
                directionToEdge = Vector2.up;
                axisVelocity    = velocity.x;
                direction       = new Vector2(axisVelocity, 0);
                forwardDistance = objectExtents.x;
                sideDistance    = objectExtents.y * DistanceToEdgeMultiplier;
            }

            var rayDistance = Mathf.Abs(axisVelocity) + forwardDistance;

            direction.Normalize();
            bool hitFirstPoint  = false;
            bool hitSecondPoint = false;
            bool hitThirdPoint  = false;

            if (rayTypes.HasFlag(RayTypes.EdgeRays))
            {
                directionToEdge *= sideDistance;
                var firstPoint  = currentPosition + directionToEdge;
                var secondPoint = currentPosition - directionToEdge;

#if UNITY_EDITOR
                var directionAndLength = direction * rayDistance;
                debugRays[0] = new Ray(firstPoint, directionAndLength);
                debugRays[1] = new Ray(secondPoint, directionAndLength);
                debugRays[2] = new Ray(currentPosition, directionAndLength);
#endif
                hitFirstPoint  = (Physics2D.RaycastNonAlloc(firstPoint, direction, firstHits, rayDistance, layerMask) > 0);
                hitSecondPoint = (Physics2D.RaycastNonAlloc(secondPoint, direction, secondHits, rayDistance, layerMask) > 0);
            }
            if (rayTypes.HasFlag(RayTypes.MiddleRay))
            {
                hitThirdPoint = (Physics2D.RaycastNonAlloc(currentPosition, direction, thirdHits, rayDistance, layerMask) > 0);
            }

            // If hit collider
            if (hitFirstPoint || hitSecondPoint || hitThirdPoint)
            {
                // Find closest point
                var firstHit  = firstHits[0];
                var secondHit = secondHits[0];
                var thirdHit  = thirdHits[0];

                float firstHitDistance  = (hitFirstPoint) ? firstHit.distance : 255;
                float secondHitDistance = (hitSecondPoint) ? secondHit.distance : 255;
                float thirdHitDistance  = (hitThirdPoint) ? thirdHit.distance : 255;

                closestHit.distance = 254;
                if (firstHitDistance < secondHitDistance)
                {
                    closestHit = firstHit;
                }
                if (closestHit.distance >= secondHitDistance)
                {
                    closestHit = secondHit;
                }
                if (closestHit.distance >= thirdHitDistance)
                {
                    closestHit = thirdHit;
                }

                if (hitFirstPoint)
                {
                    raycastHits.Add(firstHit);
                }
                if (hitSecondPoint)
                {
                    raycastHits.Add(secondHit);
                }
                if (hitThirdPoint)
                {
                    raycastHits.Add(thirdHit);
                }

                return(new NewPoint(direction * (closestHit.distance - forwardDistance)));
            }

            return(new NewPoint(false));
        }