Ejemplo n.º 1
0
        public static bool CheckLadderKind(PlayerEntity player, out LadderLocation location, bool considerDirection = false)
        {
            location = LadderLocation.Null;

            var playerTransform = player.RootGo().transform;
            var pos             = playerTransform.position;

            Vector3 capsuleBottom, capsuleUp;
            float   capsuleRadius;

            PlayerEntityUtility.GetCapsule(player, pos, out capsuleBottom,
                                           out capsuleUp, out capsuleRadius);

            //DebugDraw.DebugWireSphere(capsuleBottom, Color.red, capsuleRadius);

            var length = Physics.OverlapSphereNonAlloc(capsuleBottom, capsuleRadius, colliders, UnityLayers.ClimbLadderLayerMask);

            if (length == 0)
            {
                return(false);
            }


            location = CheckLadderLocation(colliders, length, playerTransform, considerDirection);

            return(location != LadderLocation.Null);
        }
Ejemplo n.º 2
0
        private static void ClimbUpTest(Vector3 collisionPoint, PlayerEntity player, out GenericActionKind kind,
                                        out float yTranslateOffset)
        {
            _kind            = kind = GenericActionKind.Null;
            yTranslateOffset = 0.0f;

            var playerTransform = player.RootGo().transform;
            var distance        = collisionPoint.y - playerTransform.position.y;

            if (distance < MinClimbHeight || distance > MaxClimbHeight)
            {
                return;
            }

            //最终位置能否站人
            var overlapPos = collisionPoint + playerTransform.up * 0.2f;

            PlayerEntityUtility.GetCapsule(player, overlapPos, out _capsuleBottom, out _capsuleUp,
                                           out _capsuleRadius);
            if (Physics.OverlapCapsule(_capsuleBottom, _capsuleUp, _capsuleRadius, UnityLayers.SceneCollidableLayerMask)
                .Length > 0)
            {
                return;
            }

            _kind        = kind = CheckClimbKindByDistance(distance, GenericActionKind.Climb50Cm, out yTranslateOffset);
            _matchTarget = collisionPoint;
        }
Ejemplo n.º 3
0
        public static bool IsPlayerOverlapAtPosition(PlayerEntity player, Vector3 position, int layerMask)
        {
            Vector3 p1, p2;
            float   radius;

            PlayerEntityUtility.GetCapsule(player, position, out p1, out p2, out radius);

            var colliders = Physics.OverlapCapsule(p1, p2, radius, layerMask);

            return(colliders.Length > 0);
        }
Ejemplo n.º 4
0
        private static void CreateData(PlayerEntity player)
        {
            if (null == player)
            {
                return;
            }
            var playerTransform = player.RootGo().transform;

            _overlapPos = playerTransform.position;

            PlayerEntityUtility.GetCapsule(player, _overlapPos, out _capsuleBottom,
                                           out _capsuleUp, out _capsuleRadius);
            _capsuleHeight   = _capsuleUp.y - _capsuleBottom.y;
            _capsuleBottom.y = (playerTransform.position + playerTransform.up * 0.5f).y;
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 6
0
        private static bool VaultUpTest(Vector3 collisionPoint, PlayerEntity player, out GenericActionKind kind,
                                        out float yTranslateOffset)
        {
            _kind            = kind = GenericActionKind.Null;
            yTranslateOffset = 0.0f;

            var playerTransform = player.RootGo().transform;
            var distance        = collisionPoint.y - playerTransform.position.y;

            if (distance < MinVaultHeight || distance > MaxVaultHeight)
            {
                return(false);
            }

            // 检测翻越过程中障碍
            var testPoint = new Vector3(playerTransform.position.x, collisionPoint.y, playerTransform.position.z);

            _capsuleBottom = testPoint + playerTransform.up * 0.3f;
            _capsuleUp     = _capsuleBottom + playerTransform.up * 0.5f;
            if (Physics.CapsuleCast(_capsuleBottom, _capsuleUp, 0.1f, _matchForward,
                                    1, UnityLayers.SceneCollidableLayerMask))
            {
                return(false);
            }

            //
            _overlapPos   = playerTransform.position + _matchForward * (VaultPly + 2.0f * _capsuleRadius - PlayerEntityUtility.CcSkinWidth);
            _overlapPos.y = (collisionPoint + -playerTransform.up * (VaultHeightLimit + 2 * PlayerEntityUtility.CcSkinWidth)).y;

            PlayerEntityUtility.GetCapsule(player, _overlapPos, out _capsuleBottom, out _capsuleUp,
                                           out _capsuleRadius);

//            DebugDraw.DebugWireSphere(_overlapPos, Color.red, 0.4f, 10.0f);
//            DebugDraw.DebugWireSphere(_capsuleBottom, Color.yellow, 0.4f, 10.0f);
//            DebugDraw.DebugWireSphere(_capsuleUp, Color.yellow, 0.4f, 10.0f);

            if (Physics.OverlapCapsule(_capsuleBottom, _capsuleUp, _capsuleRadius,
                                       UnityLayers.SceneCollidableLayerMask).Length > 0)
            {
                return(false);
            }

            _kind        = kind = CheckClimbKindByDistance(distance, GenericActionKind.Vault50Cm, out yTranslateOffset);
            _matchTarget = collisionPoint;
            return(true);
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        // Vault测试需在Step测试之前
        private static bool VaultUpTest(Vector3 collisionPoint, PlayerEntity player, out GenericActionKind kind, out Vector3 matchTarget)
        {
            kind        = GenericActionKind.Null;
            matchTarget = Vector3.zero;

            var playerTransform = player.RootGo().transform;
            var distance        = collisionPoint.y - playerTransform.position.y;

            if (distance < 0.8 || distance > 2.3)
            {
                return(false);
            }

            // 检测翻越过程中障碍
            _capsuleBottom.y = (collisionPoint + playerTransform.up * 0.3f).y;
            _capsuleUp.y     = _capsuleBottom.y + _capsuleHeight;
            if (Physics.CapsuleCast(_capsuleBottom, _capsuleUp, 0.1f, playerTransform.forward,
                                    1, UnityLayers.SceneCollidableLayerMask))
            {
                return(false);
            }

            // 人物当前位置,往前移动1m,往上移动0.2m
            _overlapPos = playerTransform.position + playerTransform.forward * (1.0f + _capsuleRadius) +
                          playerTransform.up * 0.2f;
            PlayerEntityUtility.GetCapsule(player, _overlapPos, out _capsuleBottom, out _capsuleUp,
                                           out _capsuleRadius);
            if (Physics.OverlapCapsule(_capsuleBottom, _capsuleUp, _capsuleRadius,
                                       UnityLayers.SceneCollidableLayerMask).Length > 0)
            {
                return(false);
            }

            kind        = GenericActionKind.Vault;
            matchTarget = collisionPoint - playerTransform.right * 0.2f;
            return(true);
        }
Ejemplo n.º 9
0
        public static bool GetRideOffPosition(PlayerEntity playerEntity, VehicleEntity vehicleEntity, Vector3 direction, out Vector3 resolvedPosition, float liftHeight = 0.01f, float displacement = 0.05f)
        {
            var         character     = playerEntity.RootGo();
            const float sweepDistance = 5.0f;

            direction = -direction;
            var p = character.transform.position - direction * sweepDistance;

            Vector3 p1, p2;
            float   radius;

            PlayerEntityUtility.GetCapsule(playerEntity, p, out p1, out p2, out radius);

            vehicleEntity.SetLayer(UnityLayerManager.GetLayerIndex(EUnityLayerName.User));

            resolvedPosition = character.transform.position;
            var hit     = new RaycastHit();
            var hitDist = 2.0f;

            var lowOffset = new Vector3(0, -0.5f, 0);

            if (Physics.CapsuleCast(p1, p2, radius, direction, out hit, sweepDistance, UnityLayerManager.GetLayerMask(EUnityLayerName.User)) ||
                //the seat position may be higher than the vehicle's height, then low the position to get collided position
                Physics.CapsuleCast(p1 + lowOffset, p2 + lowOffset, radius, direction, out hit, sweepDistance, UnityLayerManager.GetLayerMask(EUnityLayerName.User)))
            {
                hitDist = hit.distance;
            }


            {
                var distance = (hitDist - displacement) * direction;

                var colliders = Physics.OverlapCapsule(p1 + distance, p2 + distance, radius);
                if (colliders.Length > 0)
                {
                    vehicleEntity.SetLayer(UnityLayerManager.GetLayerIndex(EUnityLayerName.Vehicle));
                    return(false);
                }


                var disp     = direction * (hitDist - displacement - sweepDistance);
                var position = resolvedPosition;
                position += disp;

                if (liftHeight > 0.0f)
                {
                    RaycastHit upHit;;
                    Physics.CapsuleCast(p1 + disp, p2 + disp, radius, Vector3.up, out upHit, liftHeight);
                    position += upHit.distance * Vector3.up;
                }

                var dist = resolvedPosition - position;
                var ray  = new Ray(position, dist.normalized);

                if (Physics.Raycast(ray, out hit, dist.magnitude, UnityLayers.AllCollidableLayerMask))
                {
                    vehicleEntity.SetLayer(UnityLayerManager.GetLayerIndex(EUnityLayerName.Vehicle));
                    return(false);
                }

                resolvedPosition = position;
            }

            vehicleEntity.SetLayer(UnityLayerManager.GetLayerIndex(EUnityLayerName.Vehicle));
            return(true);
        }
Ejemplo n.º 10
0
        /**
         * 1.人物正前方做CapsuleCast(capsuleBottom向上微抬)
         * 2.hit点向上抬 探出碰撞体高 + 人物高  的距离
         * 3.向下做SphereCast(半径0.3),目的是人物所站位置与攀爬位置有一定的容错
         * 4.hit点作为攀爬点,做MatchTarget(手到hit点差值)
         * 5.人物站立位置往正前方移动1m,做OverlapCapsule,检测翻越
         */
        private void TestTrigger(PlayerEntity player)
        {
            var        playerTransform = player.RootGo().transform;
            RaycastHit hit;
            var        overlapPos = playerTransform.position;

            PlayerEntityUtility.GetCapsule(player, overlapPos, out _capsuleBottom, out _capsuleUp, out _capsuleRadius);
            var capsuleHight = _capsuleUp.y - _capsuleBottom.y;

            _capsuleBottom.y = (playerTransform.position + playerTransform.up * 0.5f).y;
            if ((null == _concretAction || !_concretAction.PlayingAnimation) &&
                Physics.CapsuleCast(_capsuleBottom, _capsuleUp, 0.001f, playerTransform.forward, out hit, 1,
                                    UnityLayers.SceneCollidableLayerMask))
            {
                //如果碰撞点到发射点的距离大于0.5
                if (hit.distance < 0.5)
                {
                    //得到碰撞点
                    Vector3 point        = hit.point;
                    Vector3 sphereCenter = new Vector3(hit.point.x, hit.collider.bounds.center.y + hit.collider.bounds.extents.y + capsuleHight, hit.point.z);

                    // 检测发射源是否处于碰撞体中
                    if (Physics.OverlapSphere(sphereCenter, 0.3f, UnityLayers.SceneCollidableLayerMask).Length >
                        0)
                    {
                        return;
                    }

                    RaycastHit sphereHit;
                    Physics.SphereCast(sphereCenter, 0.3f, Vector3.down, out sphereHit,
                                       hit.collider.bounds.center.y + hit.collider.bounds.extents.y + capsuleHight,
                                       UnityLayers.SceneCollidableLayerMask);
                    point = sphereHit.point;

                    var distance = point.y - playerTransform.position.y;
                    if (distance > 1.5 && distance < 2.3)
                    {
                        //一定高度内为climb
                        ResetConcretAction();

                        _concretAction                  = _climbAction;
                        _concretAction.MatchTarget      = point;
                        _concretAction.CanTriggerAction = true;
                    }
                    else if (distance > 0.5 && distance <= 1.5)
                    {
                        ResetConcretAction();

                        //
                        overlapPos = playerTransform.position + playerTransform.forward * (1.0f + _capsuleRadius) + playerTransform.up * 0.2f;
                        PlayerEntityUtility.GetCapsule(player, overlapPos, out _capsuleBottom, out _capsuleUp, out _capsuleRadius);
                        var casts = Physics.OverlapCapsule(_capsuleBottom, _capsuleUp, _capsuleRadius, UnityLayers.SceneCollidableLayerMask);
                        //
                        if (casts.Length <= 0 && distance > 0.8f)
                        {
                            _concretAction = _vaultAction;
                        }
                        else
                        {
                            _concretAction = _stepAction;
                        }
                        _concretAction.MatchTarget      = point;
                        _concretAction.CanTriggerAction = true;
                    }
                }
                else
                {
                    ResetConcretAction();
                }
            }
            else
            {//没有探测到障碍物
                ResetConcretAction();
            }
        }