예제 #1
0
        /// <summary>
        /// Check for steps on the way and adjust the controller.
        /// </summary>
        /// <param name="position">Next position.</param>
        /// <param name="foundStep">If a step was found.</param>
        /// <returns>Adjusted position with the possible step.</returns>
        protected virtual Vector3 MoveOnSteps(Vector3 position, Vector3 direction, out bool foundStep)
        {
            // after finding a collision, try to check if it's a step
            // the controller can be on
            foundStep = false;
            bool onGround = OnStairGroundDetect();

            if (!onGround)
            {
                return(position);
            }

            RaycastHit stepHit;
            Vector3    upCenter, downCenter;
            Vector3    center, halfExtends;
            Quaternion rot;

            _boxCollider.ToWorldSpaceBox(out center, out halfExtends, out rot);
            // override center with desired position
            center = position + _boxCollider.center + (direction * 0.01f);
            // increase hull size

            // cast up
            bool foundUp;

            foundUp = Physics.BoxCast(center, halfExtends, Vector3.up, out stepHit, Quaternion.identity, Profile.StepOffset,
                                      Profile.SurfaceLayers, QueryTriggerInteraction.Ignore);

            if (foundUp && stepHit.distance > 0)
            {
                upCenter = center + (Vector3.up * stepHit.distance);
            }
            else
            {
                upCenter = center + (Vector3.up * Profile.StepOffset);
            }

            // check if it's free
            halfExtends -= Vector3.one * Profile.HullExtends;
            int nColls = Physics.OverlapBoxNonAlloc(upCenter, halfExtends, overlapOnSteps, Quaternion.identity,
                                                    Profile.SurfaceLayers, QueryTriggerInteraction.Ignore);

            if (nColls > 0)
            {
                // still overlapping something, cancel stepping
                return(position);
            }


            // cast down
            bool foundDown;

            foundDown = Physics.BoxCast(upCenter, halfExtends, Vector3.down, out stepHit, Quaternion.identity, Profile.StepOffset,
                                        Profile.SurfaceLayers, QueryTriggerInteraction.Ignore);
            if (foundDown && stepHit.distance > 0)
            {
                downCenter = upCenter + (Vector3.down * stepHit.distance);
                DebugExtension.DrawBox(downCenter, halfExtends, Quaternion.identity, Color.yellow);
                if (downCenter.y > center.y)
                {
                    foundStep = true;
                    float upDist = Mathf.Abs(downCenter.y - center.y);
                    position.y += upDist;
                    Collisions |= CC_Collision.CollisionStep;

                    StepCount++;
                }
            }

            return(position);
        }