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); }
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); }
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); }
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); }
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); }
/// <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(); }
/// <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(); }