// 远程兵近身自我保护,逃跑 // private void SelfProtected_1() { Vector3 playerPosition = AppMap.Instance.me.GoBase.transform.position; // 主角位置 Vector3 point = _selfTransform.position; float nearDefend = _meEnemyVo.MonsterVO.near_defend * 0.1f; if (Math.Abs(playerPosition.x - _selfTransform.position.x) <= nearDefend) { if (_selfTransform.position.x < playerPosition.x) // 主角在 右边 { point.x -= (nearDefend + 0.2f); // 远程兵跑到'左边' } else // 主角在 左边 { point.x += (nearDefend + 0.2f); } MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; if (Mathf.Abs(point.y - mapRange.MinY) < Mathf.Abs(point.y - mapRange.MaxY)) {// 离下面比较近,就往上跑 point.y += 0.02f; } else { point.y -= 0.02f; } var attackVo2 = new ActionVo { ActionType = Actions.ATTACK2, // 逃跑动作 TargetPoint = point }; MeController.AttackController.AddAttackList(attackVo2); } }
void Adjust2Screen() // 使怪物移动不超出屏幕边界 { if (MeController.StatuController.CurrentStatu == Status.IDLE && MeController.StatuController.CurStatuNameHash == Status.NAME_HASH_IDLE) { if (MeVo.instance.mapId != MapTypeConst.WORLD_BOSS) { Vector3 point; MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; // 地图边界 if (_selfTransform.position.x < MapControl.Instance.MyCamera.LeftBoundX + 1) // 使怪物移动不超出屏幕边界 { float x = Mathf.Max(MapControl.Instance.MyCamera.LeftBoundX + 1, mapRange.MinX + 1); point = new Vector3(Random.Range(x, x + 1), Random.Range(mapRange.MinY, mapRange.MaxY), 0); var actionVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; // 怪物将要run动作添加进attacklist MeController.AttackController.AddAttackList(actionVo); return; } if (_selfTransform.position.x > MapControl.Instance.MyCamera.RightBoundX - 1) // 使怪物移动不超出屏幕边界 { float x = Mathf.Min(MapControl.Instance.MyCamera.RightBoundX - 1, mapRange.MaxX - 1); point = new Vector3(Random.Range(x - 1, x), Random.Range(mapRange.MinY, mapRange.MaxY), 0); var actionVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; MeController.AttackController.AddAttackList(actionVo); return; } } } }
/// <summary> /// 在min和max之间产生一个不在角色三个单位范围内的值 /// </summary> /// <returns></returns> private float GetRandomValueX() { const float minRange = 2f; //半径范围 float result = 0f; float meX = AppMap.Instance.me.Controller.transform.position.x; MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; float minX = mapRange.MinX + 2; float maxX = mapRange.MaxX - 2; if (meX - minX < minRange) { result = Random.Range(meX + minRange, maxX); } else if (meX + minRange > maxX) { result = Random.Range(minX, meX - minRange); } else { result = Random.Range(-10, 10) > 0 ? Random.Range(minX, meX - minRange) : Random.Range(meX + minRange, maxX); } return(result); }
/// <summary> /// 找到在当前副本阶段行走区域范围内最近的怪物 /// </summary> /// <returns></returns> private ActionDisplay FindNearestEnemyInMapRange() { ActionDisplay result = null; float dis = 1000000; IList <ActionDisplay> tempList = AppMap.Instance.monsterList.Cast <ActionDisplay>().ToList(); if (MeController.GetMeVo().Id == AppMap.Instance.me.GetVo().Id) { foreach (PlayerDisplay display in AppMap.Instance.playerList) { if (display != AppMap.Instance.me) { tempList.Add(display); } } } else { tempList.Add(AppMap.Instance.me); } foreach (ActionDisplay actionDisplay in tempList) { float x = actionDisplay.GoBase.transform.position.x; float y = actionDisplay.GoBase.transform.position.y; MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; if (x < mapRange.MinX || x > mapRange.MaxX || y < mapRange.MinY || y > mapRange.MaxY) { continue; } if (actionDisplay.GetMeVoByType <BaseRoleVo>().CurHp == 0) { continue; } float curDis = GeteEnemyDistance(actionDisplay); if (curDis < dis) { result = actionDisplay; dis = curDis; } } return(result); }
/// <summary> /// 没有怪物时的AI移动逻辑 /// </summary> private void AiMoveBehaviourNoEnemy() { MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; Vector3 targetPoint = _meTransform.position; if (MapMode.CanGoToNextPhase) { MeController.Me.ChangeDire(Directions.Right); MeController.MoveByDir(MeController.Me.CurFaceDire); return; } if (targetPoint.x < mapRange.MinX + 1) { MeController.Me.ChangeDire(Directions.Right); } else if (targetPoint.x > mapRange.MaxX - 1) { MeController.Me.ChangeDire(Directions.Left); } MeController.MoveByDir(MeController.Me.CurFaceDire); }
/**限制行走范围**/ public Vector3 AdjustVector3(Vector3 v) { MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; if (v.y > mapRange.MaxY) { v.y = mapRange.MaxY; } if (v.y < mapRange.MinY) { v.y = mapRange.MinY; } if (v.x > mapRange.MaxX) { v.x = mapRange.MaxX; } if (v.x < mapRange.MinX) { v.x = mapRange.MinX; } return(v); }
/**创建本玩家**/ private void CreateMe(bool isFirstIntoScene) { MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; if (AppMap.Instance.mapParser.MapVo.type != MapTypeConst.CITY_MAP) { MeVo.instance.X = mapRange.MinX + 1; MeVo.instance.Y = (mapRange.MinY + mapRange.MaxY) / 2; } else { if (!isFirstIntoScene) { MeVo.instance.X = mapRange.MaxX - Random.Range(3, 7); //在传送点旁边 MeVo.instance.Y = Random.Range(mapRange.MinY, mapRange.MaxY); } } MeDisplay me = AppMap.Instance.me; if (me != null) { me.ChangeDire(Directions.Right); InitMePos(); _myCamera.InitPos(); SetHeroIdleType(); var actionControler = me.Controller as ActionControler; if (actionControler != null) { actionControler.StopWalk(); //刚进场景的时候停止移动,防止出现误点导致的寻路 } me.SetSortingOrder(false); ChangeSceneOk(); return; } MeVo.instance.ModelLoadCallBack = LoadMeCallBack; MeVo.instance.IsUnbeatable = false; AppMap.Instance.CreateMe(MeVo.instance); }
// 远程兵近身自我保护,逃跑 // private void SelfProtected_1() { Vector3 playerPosition = AppMap.Instance.me.GoBase.transform.position; // 主角位置 Vector3 point = _selfTransform.position; float nearDefend = _meEnemyVo.MonsterVO.near_defend * 0.1f; if (Math.Abs(playerPosition.x - _selfTransform.position.x) <= nearDefend) { if (_selfTransform.position.x < playerPosition.x) // 主角在 右边 { point.x = MapControl.Instance.MyCamera.LeftBoundX; // 远程兵跑到屏幕'左边' } else // 主角在 左边 { point.x = MapControl.Instance.MyCamera.RightBoundX; } MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; if (Mathf.Abs(point.y - mapRange.MinY) < Mathf.Abs(point.y - mapRange.MaxY)) {// 离下面比较近,就往上跑 point.y = mapRange.MaxY; } else { point.y = mapRange.MinY; } _runTime = 0; var attackVo2 = new ActionVo { ActionType = Actions.RUN, // 逃跑动作 RunDestination = point }; MeController.AttackController.AddAttackList(attackVo2); } }
// Update is called once per frame private void Update() { // 获取animator的信息并根据animator信息进行相应的业务处理 if (_animator == null) { _animator = MeController.Me.Animator; return; } if (!MonsterMgr.CanSetAi) { return; } // run 3 秒就停 if (MeController.StatuController.CurrentStatu == Status.RUN) { _runTime += Time.deltaTime; if (_runTime >= 3f) { MeController.StatuController.SetStatu(Status.IDLE); } } if (MeController.StatuController.CurrentStatu == Status.IDLE && MeController.StatuController.CurStatuNameHash == Status.NAME_HASH_IDLE) { if (MeVo.instance.mapId != MapTypeConst.WORLD_BOSS) { Vector3 point; MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; // 地图边界 if (_selfTransform.position.x < MapControl.Instance.MyCamera.LeftBoundX + 1) // 使怪物移动不超出地图边界 { float x = Mathf.Max(MapControl.Instance.MyCamera.LeftBoundX + 1, mapRange.MinX + 1); point = new Vector3(Random.Range(x, x + 1), Random.Range(mapRange.MinY, mapRange.MaxY), 0); var actionVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; // 怪物将要run动作添加进attacklist _runTime = 0; MeController.AttackController.AddAttackList(actionVo); return; } if (_selfTransform.position.x > MapControl.Instance.MyCamera.RightBoundX - 1) // 使怪物移动不超出地图边界 { float x = Mathf.Min(MapControl.Instance.MyCamera.RightBoundX - 1, mapRange.MaxX - 1); point = new Vector3(Random.Range(x - 1, x), Random.Range(mapRange.MinY, mapRange.MaxY), 0); var actionVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; _runTime = 0; MeController.AttackController.AddAttackList(actionVo); return; } } } if (!IsAi) { return; } if (MeController.StatuController.CurrentStatu == Status.IDLE) { SelfProtected_1(); } }
/// <summary> /// 进入场景后初始化一次玩家位置,防止因为同步的时间差导致进副本时玩家的初始位置不正确 /// </summary> private void InitMePos() { MeDisplay me = AppMap.Instance.me; MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; if (MeVo.instance.X <= mapRange.MinX) { MeVo.instance.X = mapRange.MinX + 3f; } else if (MeVo.instance.X >= mapRange.MaxX) { MeVo.instance.X = mapRange.MaxX - 3f; } me.Pos(MeVo.instance.X, MeVo.instance.Y); if (AppMap.Instance.mapParser.MapVo.type != MapTypeConst.CITY_MAP) { if (me.Controller.GoName != null) { me.Controller.GoName.SetActive(false); //副本中不显示玩家名字 float y = me.BoxCollider2D.center.y + me.BoxCollider2D.size.y / 2; me.Controller.GoName.transform.localPosition = new Vector3(0f, y, 0f); } } else { if (me.Controller.GoName) { me.Controller.GoName.SetActive(true); float y = me.BoxCollider2D.center.y + me.BoxCollider2D.size.y / 2; me.Controller.GoName.transform.localPosition = new Vector3(0f, y + 0.3f, 0f); } } if (MeVo.instance.mapId != MapTypeConst.GoldHit_MAP) //如果是击石成金副本的话,显示面板 { Singleton <GoldHitView> .Instance.CloseView(); //大副本的界面 Singleton <GoldHitMainView> .Instance.CloseView(); } //主城避免在传送点出生 if (MapTypeConst.MajorCity == MeVo.instance.mapId) { if (AppMap.Instance.InHitPointPos(me.Controller.transform.position)) { Vector3 newPos = me.Controller.transform.position; newPos.y += (GameConst.HitPointRadius + 0.2f); me.Pos(newPos.x, newPos.y); } else if (AppMap.Instance.InWorldMapPointPos(me.Controller.transform.position)) { Vector3 newPos = me.Controller.transform.position; newPos.y += (GameConst.HitPointRadius + 0.2f); me.Pos(newPos.x, newPos.y); } } //脚底灰尘特效位置初始化 GameObject footSmokeObj = EffectMgr.Instance.GetMainEffectGameObject(EffectId.Main_FootSmoke); if (null != footSmokeObj) { footSmokeObj.transform.position = me.Controller.transform.position; } GameObject autoRoad = EffectMgr.Instance.GetMainEffectGameObject(EffectId.Main_AutoSerachRoad); if (null != autoRoad) { autoRoad.transform.position = AppMap.Instance.me.Controller.transform.position + new Vector3(0, 2.2f, 0); } if (AppMap.Instance.mapParser.NeedSyn) { RoleMode.Instance.SendStatuChange(); //主角进入场景时同步一次位置信息 } }
public static void WriteVPlusMapRange(this ZPackage pkg, MapRange mapRange) { pkg.m_writer.Write(mapRange.StartingX); pkg.m_writer.Write(mapRange.EndingX); pkg.m_writer.Write(mapRange.Y); }
// Update is called once per frame private void Update() { // 获取animator的信息并根据animator信息进行相应的业务处理 if (_animator == null) { _animator = MeController.Me.Animator; return; } if (!MonsterMgr.CanSetAi) { return; } // run 1 秒就停 if (MeController.StatuController.CurrentStatu == Status.RUN) { _runTime += Time.deltaTime; if (_runTime >= 2f) { MeController.StatuController.SetStatu(Status.IDLE); } } if (MeController.StatuController.CurrentStatu == Status.IDLE && MeController.StatuController.CurStatuNameHash == Status.NAME_HASH_IDLE) { if (MeVo.instance.mapId != MapTypeConst.WORLD_BOSS) { Vector3 point; MapRange mapRange = AppMap.Instance.mapParser.CurrentMapRange; // 地图边界 if (_selfTransform.position.x < MapControl.Instance.MyCamera.LeftBoundX + 1) // 使怪物移动不超出地图边界 { float x = Mathf.Max(MapControl.Instance.MyCamera.LeftBoundX + 1, mapRange.MinX + 1); point = new Vector3(Random.Range(x, x + 1), Random.Range(mapRange.MinY, mapRange.MaxY), 0); var actionVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; // 怪物将要run动作添加进attacklist _runTime = 0; MeController.AttackController.AddAttackList(actionVo); return; } if (_selfTransform.position.x > MapControl.Instance.MyCamera.RightBoundX - 1) // 使怪物移动不超出地图边界 { float x = Mathf.Min(MapControl.Instance.MyCamera.RightBoundX - 1, mapRange.MaxX - 1); point = new Vector3(Random.Range(x - 1, x), Random.Range(mapRange.MinY, mapRange.MaxY), 0); var actionVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; _runTime = 0; MeController.AttackController.AddAttackList(actionVo); return; } } } if (!IsAi) { return; } AnimatorStateInfo stateInfo = _animator.GetCurrentAnimatorStateInfo(0); if (stateInfo.nameHash == Status.NAME_HASH_ATTACK1 || stateInfo.nameHash == Status.NAME_HASH_ATTACK2) { if (!_checkNeedMoveAfterAttack) { _checkNeedMoveAfterAttack = true; int random = Random.Range(0, 1000); if (_meEnemyVo != null && random < _meEnemyVo.MonsterVO.attackMovePro) // attackMovePro; 攻击后游走概率 { _isMoveAfterAttack = true; } } } else { _checkNeedMoveAfterAttack = false; } if (MeController.StatuController.CurrentStatu == Status.IDLE) { _stopTime += Time.deltaTime; if (_meEnemyVo != null && _stopTime > _meEnemyVo.MonsterVO.searchStop * 0.001) // searchStop; 寻路停顿 { AiSearchBehaviour_Far(); _stopTime = 0; return; } if (_isMoveAfterAttack) { _isMoveAfterAttack = false; AiCruiseBehaviour(); return; } } else { _stopTime = 0; } if (Random.Range(0, 100) < 10) { //控制攻击频率,即直接退出 不会进行下面的攻击 return; } if (MeController.StatuController.CurrentStatu == Status.IDLE) { AiAttackBehaviour(); } }
public static void RPC_VPlusMapSync(long sender, ZPackage mapPkg) { if (ZNet.m_isServer) //Server { if (sender == ZRoutedRpc.instance.GetServerPeerID()) { return; } if (mapPkg == null) { return; } //Get number of explored areas int exploredAreaCount = mapPkg.ReadInt(); if (exploredAreaCount > 0) { //Iterate and add them to server's combined map data. for (int i = 0; i < exploredAreaCount; i++) { MapRange exploredArea = mapPkg.ReadVPlusMapRange(); for (int x = exploredArea.StartingX; x < exploredArea.EndingX; x++) { ServerMapData[exploredArea.Y * Minimap.instance.m_textureSize + x] = true; } } ZLog.Log($"Received {exploredAreaCount} map ranges from peer #{sender}."); //Send Ack VPlusAck.SendAck(sender); } //Check if this is the last chunk from the client. bool lastMapPackage = mapPkg.ReadBool(); if (!lastMapPackage) { return; //This package is one of many chunks, so don't update clients until we get all of them. } //Convert map data into ranges List <MapRange> serverExploredAreas = ExplorationDataToMapRanges(ServerMapData); //Chunk up the map data List <ZPackage> packages = ChunkMapData(serverExploredAreas); //Send the updated server map to all clients foreach (ZPackage pkg in packages) { RpcQueue.Enqueue(new RpcData() { Name = "VPlusMapSync", Payload = new object[] { pkg }, Target = ZRoutedRpc.Everybody }); } ZLog.Log($"-------------------------- Packages: {packages.Count}"); ZLog.Log($"Sent map updates to all clients ({serverExploredAreas.Count} map ranges, {packages.Count} chunks)"); } else //Client { if (sender != ZRoutedRpc.instance.GetServerPeerID()) { return; //Only bother if it's from the server. } if (mapPkg == null) { ZLog.LogWarning("Warning: Got empty map sync package from server."); return; } //Get number of explored areas int exploredAreaCount = mapPkg.ReadInt(); if (exploredAreaCount > 0) { //Iterate and add them to explored map for (int i = 0; i < exploredAreaCount; i++) { MapRange exploredArea = mapPkg.ReadVPlusMapRange(); for (int x = exploredArea.StartingX; x < exploredArea.EndingX; x++) { Minimap.instance.Explore(x, exploredArea.Y); } } //Update fog texture Minimap.instance.m_fogTexture.Apply(); ZLog.Log($"I got {exploredAreaCount} map ranges from the server!"); //Send Ack VPlusAck.SendAck(sender); } else { ZLog.Log("Server has no explored areas to sync, continuing."); } } }