コード例 #1
0
        private bool GroundTest(PlayerEntity playerEntity, out float dist)
        {
            bool ret = false;

            dist = 0f;
            var controller = playerEntity.characterContoller.Value;
            var radius     = controller.radius;
            var gameObject = playerEntity.RootGo();
            var prevLayer  = gameObject.layer;

            IntersectionDetectTool.SetColliderDisable(gameObject, IntersectionDetectTool.ColliderEnableState);
            var playerPos  = playerEntity.position.Value;
            var startPoint = new Vector3(playerPos.x, SingletonManager.Get <MapConfigManager>().WaterSurfaceHeight(playerPos), playerPos.z);
            // a shift lift up
            RaycastHit outHit;

            //DebugDraw.DebugWireSphere(startPoint + new Vector3(0,-(AnimatorParametersHash.FirstPersonStandCameraHeight - radius + DisOffset),0) , radius, 0 , false);
            if (Physics.SphereCast(startPoint, radius, Vector3.down, out outHit, AnimatorParametersHash.FirstPersonStandCameraHeight - radius + DisOffset, UnityLayers.AllCollidableLayerMask))
            {
                ret  = true;
                dist = outHit.distance + radius;
            }
            IntersectionDetectTool.RestoreCollider(gameObject, IntersectionDetectTool.ColliderEnableState);
            //_logger.InfoFormat("GroundTest : {0}", ret);
            return(ret);
        }
コード例 #2
0
        private static bool IsHitGround(PlayerEntity playerEntity, float dist)
        {
            var gameObject = playerEntity.RootGo();
            var prevLayer  = gameObject.layer;

            IntersectionDetectTool.SetColliderLayer(gameObject, UnityLayerManager.GetLayerIndex(EUnityLayerName.User));
            var startPoint  = gameObject.transform.position;
            var valueRadius = playerEntity.characterContoller.Value.radius;

            //UnityLayers.
            // a shift lift up
            startPoint = startPoint + gameObject.transform.rotation * new Vector3(0f, valueRadius, 0f);
            RaycastHit outHit;

//            DebugDraw.DebugWireSphere(startPoint, Color.red, CastRadius, 1f);
//            DebugDraw.DebugWireSphere(startPoint + new Vector3(0,targetHeight - CastRadius - LiftUp,0), Color.magenta, CastRadius, 1f);
            var isHit = PhysicsCastHelper.SphereCast(startPoint, CastRadius, Vector3.down, out outHit, dist,
                                                     UnityLayers.AllCollidableLayerMask, QueryTriggerInteraction.Ignore, 0.1f);

            //if (!isHit)
            {
                //DebugDraw.DebugWireSphere(startPoint,isHit ? Color.green : (playerEntity.characterContoller.Value.isGrounded ? Color.magenta : Color.red) ,CastRadius, isHit ? 0f:60f);
            }
            IntersectionDetectTool.SetColliderLayer(gameObject, prevLayer);
            return(isHit);
        }
コード例 #3
0
        private void JumpDisableTest(PlayerEntity playerEntity, IAdaptiveContainer <IFsmInputCommand> commandsContainer)
        {
            var state = playerEntity.stateInterface.State.GetNextPostureState();

            if (state != PostureInConfig.Stand || playerEntity.playerMove.IsGround)
            {
                return;
            }

            testCommand.Clear();

            for (int i = 0; i < commandsContainer.Length; i++)
            {
                var v = commandsContainer[i];
                if (v.Type == FsmInput.Jump)
                {
                    testCommand.Add(v);
                }
            }

            if (testCommand.Count == 0)
            {
                return;
            }

            var gameObject = playerEntity.RootGo();
            var prevLayer  = gameObject.layer;

            IntersectionDetectTool.SetColliderLayer(gameObject, UnityLayers.TempPlayerLayer);
            var startPoint = gameObject.transform.position;

            //UnityLayers.
            // a shift lift up
            startPoint.y += CastRadius;
            RaycastHit outHit;

//            DebugDraw.DebugWireSphere(startPoint, Color.red, CastRadius, 1f);
//            DebugDraw.DebugWireSphere(startPoint + new Vector3(0,targetHeight - CastRadius - LiftUp,0), Color.magenta, CastRadius, 1f);

            if (!Physics.SphereCast(startPoint, CastRadius, Vector3.down, out outHit, CastRadius + CastRadius, UnityLayers.AllCollidableLayerMask))
            {
                foreach (IFsmInputCommand command in testCommand)
                {
                    _logger.InfoFormat("chang command:{0} to none, because current state:{1} can not jump because ground is empty!",
                                       command.Type,
                                       state);
                    command.Type = FsmInput.None;
                }

                //Debug.DrawLine(outHit.point, outHit.normal, Color.red, 5000.0f);
            }
            IntersectionDetectTool.SetColliderLayer(gameObject, prevLayer);
            testCommand.Clear();
        }
コード例 #4
0
        private static bool IsHitGround(PlayerEntity playerEntity, float dist)
        {
            var        gameObject     = playerEntity.RootGo();
            var        prevLayer      = gameObject.layer;
            var        prev           = IntersectionDetectTool.SetColliderDisable(gameObject);
            var        playerPosition = gameObject.transform.position;
            var        playerRotation = gameObject.transform.rotation;
            var        controller     = playerEntity.characterContoller.Value;
            var        valueRadius    = playerEntity.characterContoller.Value.radius;
            var        isHit          = false;
            RaycastHit outHit;

            if (UseSphereCast(controller))
            {
                //use sphere cast
                var position = playerPosition + playerRotation * new Vector3(0f, valueRadius, 0f);

//            DebugDraw.DebugWireSphere(startPoint, Color.red, CastRadius, 1f);
//            DebugDraw.DebugWireSphere(startPoint + new Vector3(0,targetHeight - CastRadius - LiftUp,0), Color.magenta, CastRadius, 1f);
                isHit = PhysicsCastHelper.SphereCast(position, CastRadius, Vector3.down, out outHit, dist,
                                                     UnityLayers.AllCollidableLayerMask, QueryTriggerInteraction.Ignore, 0.1f);
                if (!isHit)
                {
                    //DebugDraw.DebugWireSphere(position + (isHit ? Vector3.down * outHit.distance : Vector3.down * dist),isHit ? Color.green : (playerEntity.characterContoller.Value.isGrounded ? Color.magenta : Color.red) ,CastRadius, isHit ? 0f:60f);
                }
            }
            else
            {
                Vector3 point1, point2;
                float   radius;
                var     height = controller.height;
                radius = controller.radius;
                var center = controller.center;
                PhysicsCastHelper.GetCapsule(controller.transform.position, controller.transform.rotation, height, radius, center, controller.direction, out point1, out point2);
                isHit = PhysicsCastHelper.CapsuleCast(point1, point2, radius, Vector3.down, out outHit, dist,
                                                      UnityLayers.AllCollidableLayerMask, QueryTriggerInteraction.Ignore, 0.1f);
                if (!isHit && false)
                {
                    PhysicsCastHelper.GetDebugDrawTypeCapsule(controller.transform.position, controller.transform.rotation, height, radius, center, controller.direction, out point1, out point2);
                    DebugDraw.DebugCapsule(point1 + (isHit ? Vector3.down * outHit.distance : Vector3.down * dist),
                                           point2 + (isHit ? Vector3.down * outHit.distance : Vector3.down * dist),
                                           isHit ? Color.green : (playerEntity.characterContoller.Value.isGrounded ? Color.magenta : Color.red),
                                           radius,
                                           isHit ? 0f:60f
                                           );
                }
            }


            IntersectionDetectTool.RestoreCollider(gameObject, prev);
            return(isHit);
        }
コード例 #5
0
        private static bool OverlapCapsuleTest(PlayerEntity playerEntity)
        {
            var gameObject = playerEntity.RootGo();

            IntersectionDetectTool.SetColliderDisable(gameObject, IntersectionDetectTool.ColliderEnableState);

            var overlapPos = gameObject.transform.position;

            PlayerEntityUtility.GetCapsule(playerEntity, overlapPos, out _capsuleBottom, out _capsuleUp,
                                           out _capsuleRadius);
            var casts = Physics.OverlapCapsule(_capsuleBottom, _capsuleUp, _capsuleRadius,
                                               UnityLayers.AllCollidableLayerMask);

            IntersectionDetectTool.RestoreCollider(gameObject, IntersectionDetectTool.ColliderEnableState);

            return(casts.Length > 0);
        }
コード例 #6
0
        private static bool OverlapCapsuleTest(PlayerEntity playerEntity)
        {
            var gameObject = playerEntity.RootGo();
            var prevLayer  = gameObject.layer;

            IntersectionDetectTool.SetColliderLayer(gameObject, UnityLayerManager.GetLayerIndex(EUnityLayerName.User));

            var overlapPos = gameObject.transform.position;

            PlayerEntityUtility.GetCapsule(playerEntity, overlapPos, out _capsuleBottom, out _capsuleUp,
                                           out _capsuleRadius);
            var casts = Physics.OverlapCapsule(_capsuleBottom, _capsuleUp, _capsuleRadius,
                                               UnityLayers.AllCollidableLayerMask);

            IntersectionDetectTool.SetColliderLayer(gameObject, prevLayer);

            return(casts.Length > 0);
        }
コード例 #7
0
        private static bool IsHitGround(PlayerEntity playerEntity, float dist)
        {
            var gameObject = playerEntity.RootGo();
            var prevLayer  = gameObject.layer;

            IntersectionDetectTool.SetColliderLayer(gameObject, UnityLayerManager.GetLayerIndex(EUnityLayerName.User));

            var startPoint = gameObject.transform.position;

            startPoint.y += _capsuleRadius;

            RaycastHit outHit;
            var        isHit = Physics.SphereCast(startPoint, _capsuleRadius, Vector3.down, out outHit, dist,
                                                  UnityLayers.AllCollidableLayerMask);

            IntersectionDetectTool.SetColliderLayer(gameObject, prevLayer);

            return(isHit);
        }
コード例 #8
0
        private static bool IsHitGround(PlayerEntity playerEntity)
        {
            var gameObject = playerEntity.RootGo();

            IntersectionDetectTool.SetColliderDisable(gameObject, IntersectionDetectTool.ColliderEnableState);

            var startPoint = gameObject.transform.position;

            startPoint.y += _capsuleRadius;

            RaycastHit outHit;
            var        dist         = CheckHitGroundDistance();
            var        hitYDistance = dist /* - ClimbStartYOffset*/;
            var        isHit        = Physics.SphereCast(startPoint, _capsuleRadius, Vector3.down, out outHit, hitYDistance,
                                                         UnityLayers.AllCollidableLayerMask);

            IntersectionDetectTool.RestoreCollider(gameObject, IntersectionDetectTool.ColliderEnableState);

            // dist高度没碰到,直接返回false
            // dist高度碰到了,但是碰撞点距离手扶点高度小于dist - VerticalDistanceDeviation 或大于dist + VerticalDistanceDeviation
            return(isHit && _matchTarget.y - outHit.point.y >= dist - VerticalDistanceDeviation &&
                   _matchTarget.y - outHit.point.y <= dist + VerticalDistanceDeviation);
        }
コード例 #9
0
        private static bool IsHitGround(PlayerEntity playerEntity, float dist)
        {
            var gameObject = playerEntity.RootGo();
            var prevLayer  = gameObject.layer;

            IntersectionDetectTool.SetColliderDisable(gameObject, IntersectionDetectTool.ColliderEnableState);
            var        playerPosition = gameObject.transform.position;
            var        playerRotation = gameObject.transform.rotation;
            var        controller     = playerEntity.characterContoller.Value;
            var        valueRadius    = playerEntity.characterContoller.Value.radius;
            var        isHit          = false;
            RaycastHit outHit;

            if (UseSphereCast(controller))
            {
                //use sphere cast
                var position = playerPosition + playerRotation * new Vector3(0f, valueRadius, 0f);

                isHit = PhysicsCastHelper.SphereCast(position, CastRadius, Vector3.down, out outHit, dist,
                                                     UnityLayers.AllCollidableLayerMask, QueryTriggerInteraction.Ignore, 0.1f);
            }
            else
            {
                Vector3 point1, point2;
                float   radius;
                var     height = controller.height;
                radius = controller.radius;
                var center = controller.center;
                PhysicsCastHelper.GetCapsule(controller.transform.position, controller.transform.rotation, height, radius, center, controller.direction, out point1, out point2);
                isHit = PhysicsCastHelper.CapsuleCast(point1, point2, radius, Vector3.down, out outHit, dist,
                                                      UnityLayers.AllCollidableLayerMask, QueryTriggerInteraction.Ignore, 0.1f);
            }


            IntersectionDetectTool.RestoreCollider(gameObject, IntersectionDetectTool.ColliderEnableState);
            return(isHit);
        }
コード例 #10
0
        /// <summary>
        /// 距离过近不能趴下
        /// </summary>
        /// <param name="playerEntity"></param>
        /// <param name="commandsContainer"></param>
        private void ProneDisableTest(PlayerEntity playerEntity, IAdaptiveContainer <IFsmInputCommand> commandsContainer)
        {
            var state         = playerEntity.stateInterface.State.GetNextPostureState();
            var characterInfo = playerEntity.characterInfo.CharacterInfoProviderContext;

            if (!(state == PostureInConfig.Stand || state == PostureInConfig.Crouch))
            {
                return;
            }

            // crouchDisable
            testCommand.Clear();
            for (int i = 0; i < commandsContainer.Length; i++)
            {
                var v = commandsContainer[i];
                if (v.Type == FsmInput.Prone)
                {
                    testCommand.Add(commandsContainer[i]);
                    _logger.DebugFormat("match type:{0}, state:{1}, in ProneDisableTest", v.Type, state);
                }
            }

            if (testCommand.Count == 0)
            {
                return;
            }


            _logger.DebugFormat("prone test!!!");

            var gameObject = playerEntity.RootGo();
            var prevLayer  = gameObject.layer;

            IntersectionDetectTool.SetColliderDisable(gameObject, IntersectionDetectTool.ColliderEnableState);

            var positionValue = playerEntity.position.Value;

            var crouchHeight =
                characterInfo.GetCrouchCapsule().Height;
            var radius =
                characterInfo.GetCrouchCapsule().Radius + RadiusOffset;
            var newCenter = new Vector3(positionValue.x, positionValue.y + crouchHeight - radius, positionValue.z);
            var distHemi  =
                characterInfo.GetStandCapsule()
                .Height * 0.5f - radius - ProneOffset;
            var topHemi    = newCenter + playerEntity.orientation.RotationYaw.Forward().normalized *distHemi;
            var bottomHemi = newCenter - playerEntity.orientation.RotationYaw.Forward().normalized *distHemi;
            //DebugDraw.EditorDrawCapsule(bottomHemi, topHemi, radius, Color.red, 1f, false);
            //_logger.InfoFormat("topHemi:{0}, bottomHei:{1},distHemi:{2}, crouchHeight:{3}, radius:{4}", topHemi.ToStringExt(), bottomHemi.ToStringExt(), distHemi,crouchHeight, radius);
            int nbUnfilteredHits = Physics.OverlapCapsuleNonAlloc(
                bottomHemi, topHemi, radius,
                IntersectionDetectTool._internalColliders,
                UnityLayers.AllCollidableLayerMask,
                QueryTriggerInteraction.Ignore);

            if (nbUnfilteredHits > 0)
            {
                foreach (IFsmInputCommand command in testCommand)
                {
                    command.Type = FsmInput.None;
                }

                playerEntity.tip.TipType = ETipType.CanNotProne;
                for (int i = 0; i < nbUnfilteredHits; ++i)
                {
                    _logger.InfoFormat("can not prone due to collider:{0}",
                                       IntersectionDetectTool._internalColliders[i].name);
                }
            }

            IntersectionDetectTool.RestoreCollider(gameObject, IntersectionDetectTool.ColliderEnableState);
            testCommand.Clear();
        }
コード例 #11
0
        /// <summary>
        /// <p>角色切换姿势会引起包围盒变化,当切换后的包围盒大于当前空间时,会无法切换姿势</p>
        /// 如:玩家站立175cm,当前空间只有160cm则无法站立。蹲趴同理
        /// </summary>
        /// <param name="playerEntity"></param>
        /// <param name="commandsContainer"></param>
        private void StandCrouchDisableTest(PlayerEntity playerEntity,
                                            IAdaptiveContainer <IFsmInputCommand> commandsContainer)
        {
            var state         = playerEntity.stateInterface.State.GetNextPostureState();
            var characterInfo = playerEntity.characterInfo.CharacterInfoProviderContext;

            if (!(state == PostureInConfig.Crouch || state == PostureInConfig.Prone))
            {
                return;
            }

            // crouchDisable
            testCondition.Clear();
            if (state == PostureInConfig.Crouch)
            {
                // to stand
                testCondition.Add(FsmInput.Jump);
                testCondition.Add(FsmInput.Crouch);
            }
            else
            {
                // to stand
                testCondition.Add(FsmInput.Jump);
                testCondition.Add(FsmInput.Prone);
                // to crouch
                testCondition.Add(FsmInput.Crouch);
            }

            testCommand.Clear();
            for (int i = 0; i < commandsContainer.Length; i++)
            {
                var v         = commandsContainer[i];
                int keyLength = testCondition.Count;
                for (int j = 0; j < keyLength; ++j)
                {
                    if (testCondition[j] == v.Type)
                    {
                        testCommand.Add(commandsContainer[i]);
                        _logger.DebugFormat("match type:{0}, state:{1}", v.Type, state);
                        break;
                    }
                }
            }

            if (testCommand.Count == 0)
            {
                return;
            }

            float targetHeight   = 0.0f;
            bool  containsCrouch = false;

            foreach (IFsmInputCommand command in testCommand)
            {
                if (command.Type == FsmInput.Crouch)
                {
                    containsCrouch = true;
                }
            }

            bool toStand = false;

            // to stand
            if (state == PostureInConfig.Crouch || (state == PostureInConfig.Prone && !containsCrouch))
            {
                targetHeight = characterInfo.GetStandCapsule().Height;
                toStand      = true;
            }
            // to crouch
            else
            {
                targetHeight = characterInfo.GetCrouchCapsule()
                               .Height;
                toStand = false;
            }

            var gameObject = playerEntity.RootGo();
            var prevLayer  = gameObject.layer;

            IntersectionDetectTool.SetColliderDisable(gameObject, IntersectionDetectTool.ColliderEnableState);
            var startPoint = gameObject.transform.position;

            //UnityLayers.
            // a shift lift up
            startPoint.y += CastRadius;
            RaycastHit outHit;

//            DebugDraw.DebugWireSphere(startPoint, Color.red, CastRadius, 1f);
//            DebugDraw.DebugWireSphere(startPoint + new Vector3(0,targetHeight - CastRadius - LiftUp,0), Color.magenta, CastRadius, 1f);

            if (PhysicsCastHelper.SphereCast(startPoint, CastRadius, Vector3.up, out outHit, targetHeight - 2
                                             * CastRadius,
                                             UnityLayers.AllCollidableLayerMask, QueryTriggerInteraction.Ignore, LiftUp))
            {
                foreach (IFsmInputCommand command in testCommand)
                {
                    _logger.InfoFormat(
                        "chang command:{0} to none, because current state:{1} can not stand up!, collider name:{2}, collid point:{3}, collider normal:{4}",
                        command.Type,
                        state,
                        outHit.collider.gameObject.name,
                        outHit.point,
                        outHit.normal);
                    command.Type = FsmInput.None;
                }

                if (toStand)
                {
                    playerEntity.tip.TipType = ETipType.CanNotStand;
                }
                else
                {
                    playerEntity.tip.TipType = ETipType.CanNotToCrouch;
                }

                //Debug.DrawLine(outHit.point, outHit.normal, Color.red, 5000.0f);
            }

            IntersectionDetectTool.RestoreCollider(gameObject, IntersectionDetectTool.ColliderEnableState);
            testCommand.Clear();
            testCondition.Clear();
        }
コード例 #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="hitPoint"></param>
        /// <param name="hitNormal"></param>
        /// <param name="maxStableSlopeAngle"></param>
        /// <param name="gameObject"></param>
        /// <returns>0 not detect 1 detect</returns>
        private int LedgeDetect(Vector3 hitPoint, Vector3 hitNormal, float maxStableSlopeAngle, GameObject gameObject)
        {
            var prevLayer = gameObject.layer;

            IntersectionDetectTool.SetColliderLayer(gameObject, UnityLayers.TempPlayerLayer);
            var     atCharacterUp     = Vector3.up;
            var     LedgeHandling     = true;
            var     InnerNormal       = hitNormal;
            var     OuterNormal       = hitNormal;
            int     LedgeDetected     = 0;
            Vector3 innerHitDirection = Vector3.ProjectOnPlane(hitNormal, atCharacterUp).normalized;

            // Ledge handling
            if (LedgeHandling)
            {
                float ledgeCheckHeight = MaxStepHeight;

                bool isStableLedgeInner = false;
                bool isStableLedgeOuter = false;

                RaycastHit innerLedgeHit;
                if (IntersectionDetectTool.CharacterCollisionsRaycast(
                        hitPoint + (atCharacterUp * SecondaryProbesVertical) + (innerHitDirection * SecondaryProbesHorizontal),
                        -atCharacterUp,
                        ledgeCheckHeight + SecondaryProbesVertical,
                        out innerLedgeHit,
                        IntersectionDetectTool._internalCharacterHits) > 0)
                {
                    InnerNormal        = innerLedgeHit.normal;
                    isStableLedgeInner = IsStableOnNormal(innerLedgeHit.normal, maxStableSlopeAngle);
                    //Debug.DrawRay(hitPoint + (atCharacterUp * SecondaryProbesVertical) + (innerHitDirection * SecondaryProbesHorizontal), InnerNormal * 10, Color.magenta, 3f);
                }

                RaycastHit outerLedgeHit;
                if (IntersectionDetectTool.CharacterCollisionsRaycast(
                        hitPoint + (atCharacterUp * SecondaryProbesVertical) + (-innerHitDirection * SecondaryProbesHorizontal),
                        -atCharacterUp,
                        ledgeCheckHeight + SecondaryProbesVertical,
                        out outerLedgeHit,
                        IntersectionDetectTool._internalCharacterHits) > 0)
                {
                    OuterNormal        = outerLedgeHit.normal;
                    isStableLedgeOuter = IsStableOnNormal(outerLedgeHit.normal, maxStableSlopeAngle);
//                    Debug.DrawRay(
//                        hitPoint + (atCharacterUp * SecondaryProbesVertical) +
//                        (-innerHitDirection * SecondaryProbesHorizontal), OuterNormal * 10, Color.blue, 3f);
                }

                LedgeDetected = (isStableLedgeInner != isStableLedgeOuter) ? 1 : LedgeDetected;
                //if (LedgeDetected == 1)
                //{
                //_logger.InfoFormat("ledge detected!!!,isStableLedgeInner:{0},isStableLedgeOuter:{1}",isStableLedgeInner,isStableLedgeOuter);
                //}
                //else
                //{
                //_logger.InfoFormat("stable inner:{0}, outer:{1}", isStableLedgeInner, isStableLedgeOuter);
                //}
                //Debug.DrawRay(hitPoint, hitNormal * 8f, Color.green, 3.0f);
            }



            IntersectionDetectTool.SetColliderLayer(gameObject, prevLayer);

            return(LedgeDetected);
        }