예제 #1
0
        // ---------------------------------------------------------------------------------------------------------
        // 2D ------------------------------------------------------------------------------------------------------
        // ---------------------------------------------------------------------------------------------------------
        static CollisionHitInfo Raycast2D(Vector3 origin, Vector3 castDirection, float castDistance, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            RaycastHit2D hitInfo2D = Physics2D.Raycast(
                origin,
                castDirection,
                castDistance,
                layerMask
                );

            hitInfo.collision = hitInfo2D.collider != null;

            if (hitInfo.collision)
            {
                hitInfo.gameObject = hitInfo2D.collider.gameObject;
            }

            hitInfo.distance = hitInfo2D.distance;
            hitInfo.point    = hitInfo2D.point;
            hitInfo.normal   = hitInfo2D.normal;

            return(hitInfo);
        }
예제 #2
0
        static CollisionHitInfo Boxcast2D(Vector3 boxCenter, Vector3 boxSize, Vector3 castDirection, float castDistance, Vector3 boxUp, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            RaycastHit2D hitInfo2D = Physics2D.BoxCast(
                boxCenter,
                boxSize,
                Utilities.SignedAngle(Vector2.up, boxUp, Vector3.forward),
                castDirection,
                castDistance,
                layerMask
                );

            hitInfo.collision = hitInfo2D.collider != null;

            if (hitInfo.collision)
            {
                hitInfo.gameObject = hitInfo2D.collider.gameObject;
            }

            hitInfo.distance = hitInfo2D.distance;
            hitInfo.point    = hitInfo2D.point;
            hitInfo.normal   = hitInfo2D.normal;

            return(hitInfo);
        }
        /// <summary>
        /// Performs a collision test in the horizontal direction (depending of the mode selected) in order to
        /// depenetrate the character from moving colliders.
        /// </summary>
        public CollisionHitInfo VerticalDepenetrationCollision(bool positiveDirection, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            float yDirection = positiveDirection ? 1 : -1;

            Vector3 castDirection = yDirection * characterBody.bodyTransform.Up;
            float   castDistance  = characterBody.height - characterBody.SkinWidth - characterBody.BoxThickness;

            // BOXCAST -------------------------------------------------------------------------------------------------------------------
            Vector3 boxCenter = positiveDirection ?
                                characterBody.middleBottomCollision + characterBody.bodyTransform.Up * (characterBody.BoxThickness / 2) :
                                characterBody.middleTopCollision - characterBody.bodyTransform.Up * (characterBody.BoxThickness / 2);


            hitInfo = PhysicsUtilities.Boxcast(
                is3D,
                boxCenter,
                characterBody.verticalBoxSize,
                castDirection,
                castDistance,
                characterBody.bodyTransform.Up,
                layerMask
                );


            return(hitInfo);
        }
예제 #4
0
        static CollisionHitInfo Boxcast3D(Vector3 boxCenter, Vector3 boxSize, Vector3 castDirection, float castDistance, Vector3 boxUp, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            RaycastHit hitInfo3D;

            Physics.BoxCast(
                boxCenter,
                boxSize / 2,
                castDirection,
                out hitInfo3D,
                Quaternion.LookRotation(Vector3.forward, boxUp),
                castDistance,
                layerMask
                );

            hitInfo.collision = hitInfo3D.collider != null;

            if (hitInfo.collision)
            {
                hitInfo.gameObject = hitInfo3D.collider.gameObject;
            }

            hitInfo.distance = hitInfo3D.distance;
            hitInfo.point    = hitInfo3D.point;
            hitInfo.normal   = hitInfo3D.normal;

            return(hitInfo);
        }
        /// <summary>
        /// Performs a collision test towards the ground.
        /// </summary>
        public CollisionHitInfo ProbeGroundCollision(float groundClampingDistance, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            if (groundClampingDistance < 0)
            {
                return(hitInfo);
            }

            float castDistance = characterBody.StepOffset + groundClampingDistance;


            // BOXCAST ----------------------------------------------------------------------------------------------------------------
            Vector3 boxCenter = characterBody.bodyTransform.Position +
                                characterBody.bodyTransform.Up * (characterBody.StepOffset + characterBody.BoxThickness / 2);

            hitInfo = PhysicsUtilities.Boxcast(
                is3D,
                boxCenter,
                characterBody.verticalBoxSize,
                -characterBody.bodyTransform.Up,
                castDistance,
                characterBody.bodyTransform.Up,
                layerMask
                );


            return(hitInfo);
        }
        /// <summary>
        /// Performs a collision detection in the vertical direction, considering the whole character characterBody.
        /// </summary>
        public CollisionHitInfo VerticalNotGroundedCollision(float deltaMovement, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            float movementSign   = Mathf.Sign(deltaMovement);
            float movementAmount = Mathf.Abs(deltaMovement);

            float   castDistance  = characterBody.SkinWidth + movementAmount;
            Vector3 castDirection = movementSign * characterBody.bodyTransform.Up;


            Vector3 boxCenter = characterBody.center +
                                movementSign * characterBody.bodyTransform.Up * (characterBody.heightExtents - characterBody.SkinWidth - characterBody.BoxThickness / 2);

            hitInfo = PhysicsUtilities.BoxCastAll(
                is3D,
                boxCenter,
                characterBody.verticalBoxSize,
                castDirection,
                castDistance,
                characterBody.bodyTransform.Up,
                results2D,
                results3D,
                layerMask
                );

            return(hitInfo);
        }
        /// <summary>
        /// Performs a collision detection in the horizontal direction, considering the whole character characterBody.
        /// </summary>
        public CollisionHitInfo HorizontalNotGroundedCollision(float deltaMovement, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            float movementSign   = Mathf.Sign(deltaMovement);
            float movementAmount = Mathf.Abs(deltaMovement);

            float   castDistance  = characterBody.SkinWidth + movementAmount;
            Vector3 castDirection = movementSign * characterBody.bodyTransform.Right;


            Vector3 boxCenter = characterBody.center +
                                movementSign * characterBody.bodyTransform.Right * (characterBody.widthExtents - characterBody.SkinWidth - (characterBody.BoxThickness) / 2);

            hitInfo = PhysicsUtilities.Boxcast(
                is3D,
                boxCenter,
                characterBody.horizontalBoxSize,
                castDirection,
                castDistance,
                characterBody.bodyTransform.Up,
                layerMask
                );

            return(hitInfo);
        }
        /// <summary>
        /// Performs a collision detection in the horizontal grounded direction.
        /// </summary>
        public CollisionHitInfo HorizontalGroundedCollision(Vector3 castDirection, bool positiveDirection, float movementAmount, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            if (movementAmount < 0)
            {
                return(hitInfo);
            }

            float castDistance = characterBody.SkinWidth + movementAmount;


            hitInfo = PhysicsUtilities.RaycastSweep(
                characterBody.Is3D(),
                positiveDirection ? characterBody.bottomRightCollision_StepOffset : characterBody.bottomLeftCollision_StepOffset,
                positiveDirection ? characterBody.topRightCollision : characterBody.topLeftCollision,
                characterBody.HorizontalRays,
                castDirection,
                castDistance,
                RaySelectionRule.ShortestNonZero,
                layerMask
                );

            return(hitInfo);
        }
        /// <summary>
        /// Performs a collision test in any of the four cardinal directions.
        /// </summary>
        public CollisionHitInfo CardinalCollision(CardinalCollisionType cardinalCollisionType, float skin, float extraDistance, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            Vector3 origin = Vector3.zero;

            float castDistance = skin + extraDistance;

            Vector3 direction = Vector3.zero;

            Vector3 center = characterBody.bodyTransform.Position + characterBody.bodyTransform.Up * characterBody.heightExtents;

            switch (cardinalCollisionType)
            {
            case CardinalCollisionType.Up:
                direction = characterBody.bodyTransform.Up;
                origin    = center + direction * (characterBody.height / 2 - skin);
                break;

            case CardinalCollisionType.Down:
                direction = -characterBody.bodyTransform.Up;
                origin    = center + direction * (characterBody.height / 2 - skin);
                break;

            case CardinalCollisionType.Left:
                direction = -characterBody.bodyTransform.Right;
                origin    = center + direction * (characterBody.width / 2 - skin);
                break;

            case CardinalCollisionType.Right:
                direction = characterBody.bodyTransform.Right;
                origin    = center + direction * (characterBody.width / 2 - skin);
                break;
            }



            hitInfo = PhysicsUtilities.Raycast(
                is3D,
                origin,
                direction,
                castDistance,
                layerMask
                );



            return(hitInfo);
        }
        /// <summary>
        /// Performs a collision test in the horizontal direction (depending of the mode selected) in order to
        /// depenetrate the character from moving colliders.
        /// </summary>
        public CollisionHitInfo HorizontalDepenetrationCollision(bool grounded, bool positiveDirection, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();


            float   xDirection    = positiveDirection ? 1 : -1;
            Vector3 castDirection = xDirection * characterBody.bodyTransform.Right;
            float   castDistance  = characterBody.width - characterBody.SkinWidth - characterBody.BoxThickness;

            hitInfo.distance = castDistance;

            Vector3 boxCenter = Vector3.zero;

            if (grounded)
            {
                boxCenter = positiveDirection ?
                            characterBody.bottomLeftCollision_StepOffset +
                            characterBody.bodyTransform.Up * (characterBody.height - characterBody.StepOffset - characterBody.SkinWidth) / 2 +
                            characterBody.bodyTransform.Right * (characterBody.BoxThickness / 2) :
                            characterBody.bottomRightCollision_StepOffset +
                            characterBody.bodyTransform.Up * (characterBody.height - characterBody.StepOffset - characterBody.SkinWidth) / 2 -
                            characterBody.bodyTransform.Right * (characterBody.BoxThickness / 2);
            }
            else
            {
                boxCenter = positiveDirection ?
                            characterBody.middleLeftCollision + characterBody.bodyTransform.Right * (characterBody.BoxThickness / 2) :
                            characterBody.middleRightCollision - characterBody.bodyTransform.Right * (characterBody.BoxThickness / 2);
            }

            hitInfo = PhysicsUtilities.Boxcast(
                is3D,
                boxCenter,
                characterBody.horizontalBoxSize,
                castDirection,
                castDistance,
                characterBody.bodyTransform.Up,
                layerMask
                );

            return(hitInfo);
        }
예제 #11
0
        static CollisionHitInfo BoxcastAll3D(Vector3 boxCenter, Vector3 boxSize, Vector3 castDirection, float castDistance, Vector3 boxUp, RaycastHit[] results, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            //RaycastHit hitInfo3D;

            int hits = Physics.BoxCastNonAlloc(
                boxCenter,
                boxSize / 2,
                castDirection,
                results,
                Quaternion.LookRotation(Vector3.forward, boxUp),
                castDistance,
                layerMask
                );

            for (int i = 0; i < hits; i++)
            {
                RaycastHit currentHitInfo3D = results[i];
                if (currentHitInfo3D.collider != null && currentHitInfo3D.distance != 0)
                {
                    hitInfo.collision = currentHitInfo3D.collider != null;

                    if (hitInfo.collision)
                    {
                        hitInfo.gameObject = currentHitInfo3D.collider.gameObject;
                    }

                    hitInfo.distance = currentHitInfo3D.distance;
                    hitInfo.point    = currentHitInfo3D.point;
                    hitInfo.normal   = currentHitInfo3D.normal;

                    break;
                }
            }

            return(hitInfo);
        }
예제 #12
0
        static CollisionHitInfo BoxcastAll2D(Vector3 boxCenter, Vector3 boxSize, Vector3 castDirection, float castDistance, Vector3 boxUp, RaycastHit2D[] results, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo2D = new CollisionHitInfo();

            hitInfo2D.Reset();

            int hits = Physics2D.BoxCastNonAlloc(
                boxCenter,
                boxSize,
                Utilities.SignedAngle(Vector2.up, boxUp, Vector3.forward),
                castDirection,
                results,
                castDistance,
                layerMask
                );

            for (int i = 0; i < hits; i++)
            {
                RaycastHit2D currentHitInfo2D = results[i];
                if (currentHitInfo2D.collider != null && currentHitInfo2D.distance != 0)
                {
                    hitInfo2D.collision = currentHitInfo2D.collider != null;

                    if (hitInfo2D.collision)
                    {
                        hitInfo2D.gameObject = currentHitInfo2D.collider.gameObject;
                    }

                    hitInfo2D.distance = currentHitInfo2D.distance;
                    hitInfo2D.point    = currentHitInfo2D.point;
                    hitInfo2D.normal   = currentHitInfo2D.normal;

                    break;
                }
            }

            return(hitInfo2D);
        }
예제 #13
0
        public static CollisionHitInfo RaycastSweep(bool is3D, Vector3 start, Vector3 end, float numberOfRays, Vector3 castDirection, float castDistance, RaySelectionRule rule, LayerMask layerMask)
        {
            CollisionHitInfo hitInfo = new CollisionHitInfo();

            hitInfo.Reset();

            float   castArea            = Vector3.Magnitude(end - start);
            Vector3 startToEndDirection = (end - start).normalized;

            hitInfo.distance = castDistance;

            CollisionHitInfo currentHitInfo;

            float step = castArea / (numberOfRays - 1);

            for (int i = 0; i < numberOfRays; i++)
            {
                Vector3 rayOrigin = start + startToEndDirection * step * i;

                // Debug.DrawRay( rayOrigin , castDirection * castDistance , Color.magenta );

                currentHitInfo = PhysicsUtilities.Raycast(
                    is3D,
                    rayOrigin,
                    castDirection,
                    castDistance,
                    layerMask
                    );


                if (!currentHitInfo.collision)
                {
                    continue;
                }

                switch (rule)
                {
                case RaySelectionRule.Shortest:

                    if (currentHitInfo.distance < hitInfo.distance)
                    {
                        hitInfo = currentHitInfo;
                    }

                    break;

                case RaySelectionRule.ShortestNonZero:

                    if (currentHitInfo.distance != 0 && currentHitInfo.distance < hitInfo.distance)
                    {
                        hitInfo = currentHitInfo;
                    }
                    break;

                case RaySelectionRule.Longest:

                    if (currentHitInfo.distance > hitInfo.distance)
                    {
                        hitInfo = currentHitInfo;
                    }

                    break;
                }
            }

            return(hitInfo);
        }