/// <summary> /// 战斗AI行为,如果攻击范围内有怪物则进行攻击 /// </summary> private void AiAttackBehaviour() { SysMapVo vo = BaseDataMgr.instance.GetMapVo(AppMap.Instance.mapParser.MapId); //副本里面的玩家的自动攻击 if (vo.type == MapTypeConst.COPY_MAP) { IEnumerable <ActionDisplay> enemyList = GetEnemyDisplay(); foreach (ActionDisplay display in enemyList) { var baseRoleVo = display.GetVo() as BaseRoleVo; if (baseRoleVo != null && baseRoleVo.CurHp <= 0) { continue; } if (display.Controller == null) { continue; } if (Mathf.Abs(display.Controller.transform.position.x - MeController.transform.position.x) <= 1.4 && Mathf.Abs(display.Controller.transform.position.y - MeController.transform.position.y) <= 0.4) { var attackVo = new ActionVo { ActionType = Actions.ATTACK, TargetPoint = display.GoBase.transform.position }; StartCoroutine(YieldSecordsAutoAttack(0.5f, attackVo)); break; } } } }
// 远程兵近身自我保护,逃跑 // 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); } }
/// <summary> /// 处于普通攻击2状态时的状态处理 /// </summary> /// <param name="stateInfo">当前动画状态信息</param> protected void ProcessAttack2State(AnimatorStateInfo stateInfo) { if (CurrentStatu == Status.ATTACK2 && CurrentCombStatu == Status.COMB_0) { CurrentCombStatu = Status.COMB_1; MeControler.SkillController.RequestUseSkill(SkillController.Attack2); } if (stateInfo.normalizedTime > 0.6 && CurrentStatu == Status.ATTACK2) { judgeNormalCombIfLongkey(); if (MeControler.AttackController.AttackList.Count > 0 && MeControler.SkillController.SkillList.Count == 0) { ActionVo actionVo = MeControler.AttackController.AttackList[0]; if (actionVo.ActionType == Actions.ATTACK) { MeControler.AttackController.AttackList.RemoveAt(0); SetStatu(Status.ATTACK3); CurrentCombStatu = Status.COMB_1; } else { CurrentCombStatu = Status.COMB_2; SetStatu(Status.IDLE); } } else { CurrentCombStatu = Status.COMB_2; SetStatu(Status.IDLE); } } }
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; } } } }
public bool TryTalentAttack() { if (_talentSkillVo.target_type == PetAiController.TargetEnemy) { if (Time.time - LastAttackTime > _talentSkillVo.cd * 0.001) { foreach (MonsterDisplay display in AppMap.Instance.monsterList) { var baseRoleVo = display.GetVo() as BaseRoleVo; if (baseRoleVo.CurHp == 0) { continue; } Vector3 petPosition = display.Controller.transform.position; Vector3 monsterPosition = MeController.transform.position; if (Math.Abs(petPosition.x - monsterPosition.x) < _talentSkillVo.cover_width * 0.001f && Math.Abs(petPosition.y - monsterPosition.y) < _talentSkillVo.cover_thickness * 0.001f * 0.5f) { var attackVo = new ActionVo { ActionType = Actions.ATTACK, TargetPoint = display.GoBase.transform.position }; MeController.AttackController.AddAttackList(attackVo); MeController.TalentSkillController.LastAttackTime = Time.time; return(true); break; } } } } return(false); }
// // 远程兵近身自我保护,不逃跑(跑到攻击范围处进行攻击) // private void SelfProtected_2() { Vector3 playerPosition = AppMap.Instance.me.GoBase.transform.position; // 主角位置 Vector3 point = _selfTransform.position; float attackRange = _meEnemyVo.MonsterVO.attack_range * 0.1f; if (Math.Abs(playerPosition.x - _selfTransform.position.x) <= attackRange) { if (_selfTransform.position.x < playerPosition.x) // 主角在 右边 { point.x -= _meEnemyVo.MonsterVO.attack_range; // 远程兵跑到'左边'攻击范围处 } else { point.x += _meEnemyVo.MonsterVO.attack_range; // 远程兵跑到'右边'攻击范围处 } point.y = point.y + Random.Range(-300, 300) * 0.001f; var attackVo2 = new ActionVo { ActionType = Actions.RUN, // 跑到攻击范围 RunDestination = point }; MeController.AttackController.AddAttackList(attackVo2); } }
override public void BeAttacked(ActionVo actionVo) { base.BeAttacked(actionVo); actionVo.Target = meController.Me.GoBase; // 显示特效的目标对象 meController.AttackController.ShowBeAttackedEffect(actionVo); //只要受击了就显示受击特效 meController.Me.StartShowModelBeAttackedEffect(); /*var statu = meController.StatuController.CurrentStatu; * if (statu == Status.IDLE || statu == Status.RUN) * { * int dir = actionVo.SkillUsePoint.x < meController.Me.GoBase.transform.position.x ? Directions.Left : Directions.Right; * meController.Me.ChangeDire(dir); //攻击过程中受击不转身 * }*/ //meController.gameObject.transform.position = actionVo.HurtDestination;//不需要 if (actionVo.HurtAnimation == Actions.Hurt1) { SetHurt1(actionVo); } else if (actionVo.HurtAnimation == Actions.Hurt2) { SetHurt2(actionVo); } /*播放受击动画间隔(不需要) * if (Time.realtimeSinceStartup - _lastBeAttackedInterval > BeAttackedCheckInterval) * { * _beAttackedTimes = 1; * } * else * { * if (_beAttackedTimes > MaxHurtActionInInterval) * { * return; * } * } * if (Time.realtimeSinceStartup - _lastBeAttackedInterval < BeAttackedCheckInterval) * { * return; * } * if (meController.StatuController.CurrentStatu == Status.HURT1) * { * meController.StatuController.SetStatu(Status.HURT2); * } * else * { * meController.StatuController.SetStatu(Status.HURT1); * } * _beAttackedTimes++; * _lastBeAttackedInterval = Time.realtimeSinceStartup;*/ int monsterNumber = AppMap.Instance.MonsterNumber; if (monsterNumber > 0 && monsterNumber <= 4) { SpeechMgr.Instance.PlayAttackedAndMonster0to4Speech(); } else if (monsterNumber > 4 && monsterNumber <= 7) { SpeechMgr.Instance.PlayAttackedAndMonster4to7Speech(); } }
public bool TrapColliderCheckInjured2D(SysSkillBaseVo skillVo, Vector3 excutePos, int dir, BoxCollider2D boxCollider2D, List <ActionDisplay> lastAttackedActionDisplay, bool isSend = false) { if (AppMap.Instance.me.GetVo().CurHp <= 0) { lastAttackedActionDisplay.Clear(); return(false); } Vector3 target = AppMap.Instance.me.Controller.transform.position; //敌方位置 bool isDodge = false; //是否闪避 bool isCrit = false; //是否暴击 bool isParry = false; //是否格挡 if (IsTrapSkillCovered(boxCollider2D, AppMap.Instance.me.BoxCollider2D)) { if (!isSend) { if (lastAttackedActionDisplay.Contains(AppMap.Instance.me)) { return(false); } var meVo = AppMap.Instance.me.GetMeVoByType <PlayerVo>(); if (meVo != null && (meVo.IsUnbeatable || AppMap.Instance.me.Controller.StatuController.CurrentStatu == Status.ROLL)) { return(false); //无敌状态不播放受击 } var attackVo = new ActionVo { SkillId = skillVo.unikey, ActionType = Actions.INJURED, SkillUsePoint = excutePos, Target = AppMap.Instance.me.GoBase }; //动作vo meControler.BeAttackedController.BeAttacked(attackVo); int cutHp = skillVo.value; //伤害值 if (meVo.CurHp <= (uint)cutHp) { meVo.CurHp = 0; attackVo = new ActionVo(); attackVo.ActionType = Actions.DEATH; meControler.AttackController.AddAttackList(attackVo, true); } else { meVo.CurHp -= (uint)cutHp; } lastAttackedActionDisplay.Add(AppMap.Instance.me); PlayerAiController.AddHudView(isDodge, isCrit, isParry, cutHp, (int)meVo.CurHp, Color.red); //冒血直接冒 return(true); } } lastAttackedActionDisplay.Clear(); return(false); }
/// <summary> /// AI巡逻行为 a 主要是:ActionType = Actions.RUN , MeController.AttackController.AddAttackList(actionVo); /// 函数功能:使怪物靠近 主角: /// 1. 在attack2攻击范围‘外’,则向主角方向移动 searchLength 距离 /// 2. 主角在attack1攻击范围‘外’,attack2‘内,则 移动 searchLength 或 -= attackRange1,看概率 /// 3. 主角在attack1攻击范围‘内’ /// </summary> private void AiSearchBehaviour_Far() { if (_meEnemyVo == null || _meEnemyVo.MonsterVO.attack_range == 0) { return; } Vector3 PlayerPoint = AppMap.Instance.me.GoBase.transform.position; // 主角位置 Vector3 targetPoint = _selfTransform.position; float attackRange = _meEnemyVo.MonsterVO.attack_range * 0.1f; bool needFellow = false; float n = Random.Range(0, 10f); if (n < 5) { targetPoint.x = PlayerPoint.x - attackRange; // 移动到主角左边 攻击范围处; } else { targetPoint.x = PlayerPoint.x + attackRange; // 移动到主角右边 攻击范围处; } /* * if (_selfTransform.position.x < PlayerPoint.x) // 主角在 右边 * { * if (_selfTransform.position.x + attackRange < PlayerPoint.x) * { * targetPoint.x = PlayerPoint.x - attackRange; // 移动到攻击范围处; * } * else * { * targetPoint.x = _selfTransform.position.x; * } * needFellow = true; * } * else // 主角在 左边 * { * if (_selfTransform.position.x - attackRange > PlayerPoint.x) * { * targetPoint.x = PlayerPoint.x - attackRange; // 移动到攻击范围处; * } * else * { * targetPoint.x = _selfTransform.position.x; * } * needFellow = true; * } */ targetPoint.y = PlayerPoint.y + Random.Range(-40, 40) * 0.01f; _runTime = 0; _stopTime = 0; var actionVo = new ActionVo { RunDestination = targetPoint, ActionType = Actions.RUN }; MeController.AttackController.AddAttackList(actionVo); }
public void addNormalAttack(bool _useAi) { AiController.SetAi(_useAi); var vo = new ActionVo { ActionType = Actions.ATTACK }; AttackController.AddAttackList(vo); }
/// <summary> /// 攻击者攻击后产生的力反馈效果 /// </summary> public void ForceFeedBack(ActionVo vo) { if (vo.ForceFeedBack > 0) { var meVo = MeController.GetMeVo(); meVo.ForceFeedBackTime = vo.ForceFeedBack * 0.001f; meVo.IsForceFeedBack = true; } }
/// <summary> /// 移动和怪物同一Y值 /// </summary> /// <param name="enemyDisplay"></param> private void MoveToTheSameYWithEnemy(ActionDisplay enemyDisplay) { Vector3 targetPoint = _meTransform.position; targetPoint.y = enemyDisplay.Controller.transform.position.y; var actionVo = new ActionVo { RunDestination = targetPoint, ActionType = Actions.RUN }; MeController.AttackController.AddAttackList(actionVo); }
/// <summary> /// 获取技能攻击后的目标表现Vo /// </summary> /// <param name="skillVo"></param> /// <param name="excutePos"></param> /// <param name="dir"></param> /// <param name="enemyDisplay"></param> /// <param name="checkedTime"></param> /// <param name="moveRatio"></param> /// <returns></returns> private ActionVo GetSkillActionVo(SysSkillBaseVo skillVo, Vector3 excutePos, int dir, ActionDisplay enemyDisplay, int index, int checkedTime = 0, float moveRatio = 1) { var attackVo = new ActionVo { ActionType = Actions.INJURED, SkillUsePoint = excutePos, SkillId = skillVo.unikey }; /* * Vector3 moveToPoint = enemyDisplay.GoBase.transform.position; * if (skillVo.target_dir != 2 && checkedTime == 0) * { * if (dir == Directions.Left) * { * moveToPoint.x -= skillVo.back_dis*0.001f*moveRatio; * } * else * { * moveToPoint.x += skillVo.back_dis*0.001f*moveRatio; * } * } * if (MeVo.instance.mapId != MapTypeConst.WORLD_BOSS) //世界BOSS的位置不受影响 * { * moveToPoint.x = AppMap.Instance.mapParser.GetFinalMonsterX(moveToPoint.x); //限制怪物被攻击后不要出屏幕 * } * moveToPoint.y = enemyDisplay.GoBase.transform.position.y; //后退时保持高度不变 * attackVo.HurtDestination = moveToPoint;*/ attackVo.FloatingValue = skillVo.Floating_Value; if (MeVo.instance.mapId != MapTypeConst.WORLD_BOSS) //世界BOSS的位置不受影响 { //获取当前攻击点的攻击数据 int[][] atkList = StringUtils.Get2DArrayStringToInt(skillVo.Per_Atk_Data); if (atkList != null) { if (index < atkList.Length) { attackVo.Velocity_Origin = atkList[index][Actions.VELOCITY_ORIGIN] * 0.001f; attackVo.Angle = atkList[index][Actions.ANGLE]; attackVo.ProtectValue = atkList[index][Actions.PROTECTVALUE]; attackVo.ForceFeedBack = atkList[index][Actions.FORCEFEEDBACK]; attackVo.HitRecover = atkList[index][Actions.HITRECOVER]; attackVo.HurtAnimation = atkList[index][Actions.HURTANIMATION]; attackVo.FaceDirection = (dir == Directions.Left ? -1 : 1); } } } return(attackVo); }
/// <summary> /// AI攻击行为 主要是:ActionType = Actions.ATTACK , MeController.AttackController.AddAttackList(actionVo); /// </summary> private void AiAttackBehaviour() { if (_meEnemyVo == null) { return; } foreach (PlayerDisplay display in AppMap.Instance.playerList) { BaseRoleVo baseRoleVo = display.GetVo(); if (baseRoleVo != null && baseRoleVo.CurHp <= 0) { continue; } Vector3 playerPosition = display.Controller.transform.position; // 主角位置; Vector3 monsterPosition = _selfTransform.position; // 怪本身位置; //float attackRange = _meEnemyVo.MonsterVO.sight_range*0.001f; // 攻击范围比如 1600 float attackRange = _meEnemyVo.MonsterVO.attack_range * 0.1f; //if (Math.Abs(playerPosition.x - monsterPosition.x) < attackRange && _meEnemyVo.CurHp > 0) if (Math.Abs(playerPosition.x - monsterPosition.x) < attackRange && _meEnemyVo.CurHp > 0 && Math.Abs(playerPosition.y - monsterPosition.y) < 0.4f) // 增加y轴的判断,应该还要增加一个 面向 的判断 { if (_meEnemyVo.CurHp < _meEnemyVo.MonsterVO.blood_change_state) {// 当血量小于‘值’时换套攻击动作,目前该动作还没添加 new var attackVo2 = new ActionVo { ActionType = Actions.ATTACK2, TargetPoint = display.GoBase.transform.position }; print("****新攻击动作"); MeController.AttackController.AddAttackList(attackVo2); break; } else { var attackVo = new ActionVo { ActionType = Actions.ATTACK, // 动作的行为,比如attack,或者run TargetPoint = display.GoBase.transform.position //GoBase 游戏模型的挂载体,即怪物要攻击的主角; }; MeController.AttackController.AddAttackList(attackVo); break; } } } }
/// <summary> /// 执行动作添加到队列 /// </summary> /// <param name="vo">动作信息</param> /// <param name="isPush">强插入,技能强制插入,普通攻击加入队列</param> public override void AddAttackList(ActionVo vo, bool isPush = false) { var playerVo = MeController.Me.GetVo() as PlayerVo; playerVo.CurHp = DangJiTester.playerVoCurHp; // grsyh if (playerVo != null && (playerVo.CurHp <= 0 && vo.ActionType != Actions.DEATH)) { return; } if (AttackList == null) { AttackList = new List <ActionVo>(); } //死亡立即播放,死亡控制可放在单独的死亡控制类里面 if (vo.ActionType == Actions.DEATH) { AttackList.Clear(); AttackList.Add(vo); return; } //强制插入 if (isPush) { if (IsInBattle()) { return; } CurVo = null; AttackList.Clear(); AttackList.Add(vo); return; } if (MeController.StatuController.CurrentStatu == Status.IDLE || MeController.StatuController.CurrentStatu == Status.RUN || MeController.StatuController.CurrentStatu == Status.ATTACK1 || MeController.StatuController.CurrentStatu == Status.ATTACK2 || MeController.StatuController.CurrentStatu == Status.ATTACK3) { if (AttackList.Count >= MeController.StatuController.MaxComb && MeController.StatuController.MaxComb > 1) { return; } AttackList.Add(vo); } }
private void AiMoveToScreenCenter() { Vector3 targetPoint = _selfTransform.position; MyCamera myCamera = MapControl.Instance.MyCamera; if (targetPoint.x < myCamera.LeftBoundX + 1.5f) { targetPoint.x = Random.Range(myCamera.LeftBoundX + 2.1f, myCamera.LeftBoundX + 3.5f); } else if (targetPoint.x > myCamera.RightBoundX - 2.1f) { targetPoint.x = Random.Range(myCamera.RightBoundX - 2.1f, myCamera.RightBoundX - 3.5f); } var actionVo = new ActionVo { RunDestination = targetPoint, ActionType = Actions.RUN }; MeController.AttackController.AddAttackList(actionVo); }
/// <summary> /// 执行动作添加到队列 /// </summary> /// <param name = "vo">动作信息</param> /// <param name = "isPush">强插入</param> override public void AddAttackList(ActionVo vo, bool isPush = false) { var petVo = MeController.Me.GetVo() as PetVo; if (petVo != null && (petVo.CurHp <= 0 && vo.ActionType != Actions.DEATH)) { return; } if (AttackList == null) { AttackList = new List <ActionVo>(); } //死亡立即播放,死亡控制可放在单独的死亡控制类里面 if (vo.ActionType == Actions.DEATH) { AttackList.Clear(); AttackList.Add(vo); return; } //如果在翻滚状态,则不会受到伤害 if (MeController.StatuController.CurrentStatu == Status.ROLL && vo.ActionType == Actions.INJURED) { return; } //强制插入 if (isPush) { CurVo = null; AttackList.Clear(); AttackList.Add(vo); return; } if (MeController.StatuController.CurrentStatu == Status.IDLE || MeController.StatuController.CurrentStatu == Status.RUN) { //attackList.Clear(); AttackList.Add(vo); } }
/// <summary> /// 攻击后游走行为 主要是:ActionType = Actions.RUN , MeController.AttackController.AddAttackList(actionVo); /// </summary> private void AiCruiseBehaviour() { if (_meEnemyVo == null) { return; } Vector3 point = AppMap.Instance.me.GoBase.transform.position; // GoBase,怪是MonsterDisplay,me 是MeDisplay bool needFellow = false; if (_selfTransform.position.x < point.x) // 主角在右边, MeController = MonsterDisplay { point.x = MeController.transform.position.x - _meEnemyVo.MonsterVO.searchLength; // searchLength 寻路步长, float maxX = MapControl.Instance.MyCamera.RightBoundX - 3; if (point.x > maxX) // 不能超出‘右边’屏幕范围 { point.x = maxX; } point.y = point.y + Random.Range(-150, 150) * 0.01f; needFellow = true; } else if (_selfTransform.position.x > point.x) // 主角在左边 { point.x = _selfTransform.position.x + _meEnemyVo.MonsterVO.searchLength; // 被打了就往右走,即离开 float minX = MapControl.Instance.MyCamera.LeftBoundX + 3; if (point.x < minX) // 不能超出‘左边’屏幕范围 { point.x = minX; } point.y = point.y + Random.Range(-150, 150) * 0.01f; needFellow = true; } if (needFellow) { _stopTime = 0; var attackVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; MeController.AttackController.AddAttackList(attackVo, true); } }
//显示受击特效 public void ShowBeAttackedEffect(ActionVo vo, float zoom = 1f, float rotateZ = 0f) { if (null == vo) { return; } string effectId = GetTargetEffectId(vo.SkillId, vo.HurtEffectIndex, vo.IsBullet); var effectVo = new Effect { URL = UrlUtils.GetSkillEffectUrl(effectId), Direction = (MeController.transform.position.x > vo.SkillUsePoint.x) ? Directions.Right : Directions.Left, BasePosition = MeController.transform.position, Offset = new Vector3(0f, 0.55f, 0f), Target = vo.Target, Zoom = zoom, EulerAngles = new Vector3(0f, 0f, rotateZ), NeedCache = true }; EffectMgr.Instance.CreateSkillEffect(effectVo); }
/// <summary> /// AI寻路行为 // 移动到 可以攻击敌人的 那个位置 /// </summary> private void AiSearchBehaviour() { Vector3 point = MeController.Me.GoBase.transform.position; float distance = 1000; //1000已经够大了 Vector3 target = point; foreach (ActionDisplay display in GetEnemyDisplay()) // 找出最近的一个敌人 { float temDis = Mathf.Abs(display.GoBase.transform.position.x - point.x); if (temDis < distance) { distance = temDis; target = display.GoBase.transform.position; } } const float attackRange = 1f; bool needFellow = false; if (point.x < target.x - attackRange) // 太近了 { point.x = target.x - attackRange; // 移动到攻击范围的那个点 needFellow = true; } else if (point.x > target.x + attackRange) // 太远了 { point.x = target.x + attackRange; // 移动到攻击范围的那个点 needFellow = true; } if (needFellow) { _stopTime = 0; var actionVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; MeController.AttackController.AddAttackList(actionVo); } }
// 远程兵近身自我保护,逃跑 // 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> /// <param name="atker">攻击者</param> /// <param name="skillVo">技能VO</param> /// <param name="effectPos">施法点,怪物位置或远程施法点</param> /// <param name="ownerPos">施法点,怪物位置或远程施法点</param> /// <param name="dir">施法方向</param> /// <param name="monsterVo">怪物VO</param> /// <param name="isSend">是否同步给服务器</param> public bool MonsterCheckInjured2D(BaseControler atker, SysSkillBaseVo skillVo, Vector3 effectPos, Vector3 ownerPos, int dir, MonsterVo monsterVo, int index, bool isSend = false) { if (AppMap.Instance.me == null || AppMap.Instance.me.GetVo().CurHp <= 0) { return(false); } if (monsterVo.CurHp <= 0) { return(false); //如果检测时当前怪物的血量已经为0,则玩家忽略当前怪物的攻击 } var meVo = AppMap.Instance.me.GetMeVoByType <PlayerVo>(); if (MeVo.instance.mapId == MapTypeConst.WORLD_BOSS) { if (AppMap.Instance.me.Controller.transform.position.x > 7) { meVo.CurHp = 0; var attackVo = new ActionVo(); attackVo.ActionType = Actions.DEATH; meControler.AttackController.AddAttackList(attackVo, true); return(true); } return(false); } Vector3 target = AppMap.Instance.me.Controller.transform.position; //敌方位置 bool isDodge = false; //是否闪避 bool isCrit = false; //是否暴击 bool isParry = false; //是否格挡 BoxCollider2D myBoxCollider2D = (meControler.Me as ActionDisplay).BoxCollider2D; BoxCollider2D enemyBoxCollider2D = AppMap.Instance.me.BoxCollider2D; if (IsSkillCovered(skillVo, effectPos, ownerPos, target, dir, myBoxCollider2D, enemyBoxCollider2D)) { if (!isSend) { int damageVal; uint damageType; uint stateType; if (meVo != null && (meVo.IsUnbeatable || AppMap.Instance.me.Controller.StatuController.CurrentStatu == Status.ROLL)) { return(false); //无敌状态不播放受击 } ActionVo attackVo = GetSkillActionVo(skillVo, effectPos, dir, AppMap.Instance.me, index); //怪物的伤害计算 GameFormula.CalcDamage(monsterVo, meVo, skillVo, out damageVal, out damageType, out stateType); switch (damageType) { case GameConst.DAMAGE_TYPE_MISS: isDodge = true; break; case GameConst.DAMAGE_TYPE_CRIT: isCrit = true; break; } if (!isDodge)//命中后,攻击者产生力反馈,受击者处理受击逻辑 { atker.AttackController.ForceFeedBack(attackVo); meControler.BeAttackedController.BeAttacked(attackVo); } int cutHp = damageVal; //伤害值 if (MeVo.instance.mapId == MapTypeConst.FirstFightMap && (meVo.CurHp < meVo.Hp * 0.3f || meVo.CurHp <= (uint)cutHp)) { cutHp = 0; isDodge = true; } else { if (meVo.CurHp <= (uint)cutHp) { meVo.CurHp = 0; attackVo = new ActionVo(); attackVo.ActionType = Actions.DEATH; meControler.AttackController.AddAttackList(attackVo, true); } else { meVo.CurHp -= (uint)cutHp; } } PlayerAiController.AddHudView(isDodge, isCrit, isParry, cutHp, (int)meVo.CurHp, Color.yellow); //冒血直接冒 //攻击后重置受击抵抗属性 monsterVo.HurtResist = (uint)monsterVo.MonsterVO.hurt_resist; return(true); } } monsterVo.HurtResist = (uint)monsterVo.MonsterVO.hurt_resist; return(false); }
public override void BeAttacked(ActionVo actionVo) { base.BeAttacked(actionVo); actionVo.Target = meController.Me.GoCloth; // 显示特效的目标对象 float zoom = Random.Range(5, 10) / 5f; float rotateZ = Random.Range(0, 360); meController.AttackController.ShowBeAttackedEffect(actionVo, zoom, rotateZ); //只要受击了就显示受击特效,怪物受击特效大小随机 meController.Me.StartShowModelBeAttackedEffect(); var monsterVo = meController.GetMeVoByType <MonsterVo>(); if (meController.StatuController.CurrentStatu == Status.ATTACK1 || meController.StatuController.CurrentStatu == Status.ATTACK2) { if (meController.AnimationParameter.IsWarning /*!meController.AnimationParameter.IsWarning*/) { return; } } //浮空处理 /* * if (monsterVo.LeftFloatingTime > 0 && monsterVo.CurrentFloatingNumber < BaseRoleVo.MaxFloatingNumber) * { * monsterVo.CurrentFloatingNumber++; * monsterVo.LeftFloatingTime = monsterVo.CurrentFloatingNumber == BaseRoleVo.MaxFloatingNumber * ? 0.6f * : 0.5f; * return; * } * if (actionVo.FloatingValue > monsterVo.MonsterVO.Floating_Resist) * { * if (monsterVo.LeftFloatingTime > 0) * { * monsterVo.CurrentFloatingNumber = 1; * monsterVo.LeftFloatingTime = 0.5f; * } * else * { * monsterVo.IsFloating = true; * } * }*/ //受击后按照受击方向产生击飞 if (actionVo.Velocity_Origin > 0) { monsterVo.FloatingXSpeed = actionVo.Velocity_Origin * Mathf.Cos(actionVo.Angle * Mathf.PI / 180f); monsterVo.FloatingYSpeed = actionVo.Velocity_Origin * Mathf.Sin(actionVo.Angle * Mathf.PI / 180f); monsterVo.AtkerDirection = actionVo.FaceDirection; SetHurt4(actionVo); return; } if (meController.IsFloating()) { SetHurt4(actionVo); return; } //受击处理 /* * if (monsterVo.HurtResist >= 100) * { * return; * } * if (monsterVo.HurtResist > 0) * { * monsterVo.HurtResist += 5; * } * if (monsterVo.HurtResist >= 100) * { * if (meController.Me.DefenceEffect == null) * { * Vector3 pos = Vector3.zero; * BoxCollider2D boxCollider2D = meController.GetMeByType<MonsterDisplay>().BoxCollider2D; * float y = (boxCollider2D.center.y + boxCollider2D.size.y/2)* * meController.Me.GoCloth.transform.localScale.y; * pos.y = y + 0.6f; * GameObject monsterFranticEffect = * EffectMgr.Instance.GetSkillEffectGameObject(EffectId.Skill_MonsterFrantic); * meController.Me.DefenceEffect = Instantiate(monsterFranticEffect) as GameObject; * if (meController.Me.DefenceEffect != null) * { * meController.Me.DefenceEffect.transform.parent = meController.Me.GoBase.transform; * meController.Me.DefenceEffect.transform.localPosition = pos; * meController.Me.DefenceEffect.SetActive(true); * } * } * else * { * Vector3 pos = Vector3.zero; * BoxCollider2D boxCollider2D = meController.GetMeByType<MonsterDisplay>().BoxCollider2D; * float y = (boxCollider2D.center.y + boxCollider2D.size.y/2)* * meController.Me.GoCloth.transform.localScale.y; * pos.y = y + 0.6f; * meController.Me.DefenceEffect.transform.localPosition = pos; * } * }*/ int dir = actionVo.SkillUsePoint.x < meController.Me.GoBase.transform.position.x ? Directions.Left : Directions.Right; meController.Me.ChangeDire(dir); //meController.gameObject.transform.position = actionVo.HurtDestination;//不需要 switch (actionVo.HurtType) { //根据原因来执行相应的受击表现 case Actions.HurtNormal: /* * if (meController.StatuController.CurrentStatu == Status.HURT1 || meController.StatuController.CurrentStatu == Status.Hurt1Recover) * { * meController.StatuController.SetStatu(Status.HURT2); * } * else * { * meController.StatuController.SetStatu(Status.HURT1); * }*/ monsterVo.ProtectValue += actionVo.ProtectValue; if (!monsterVo.IsProtecting) { if (actionVo.HurtAnimation == 1) { SetHurt1(actionVo); } else if (actionVo.HurtAnimation == 2) { SetHurt2(actionVo); } } else { SetHurt3(actionVo); } break; case Actions.HurtFly: if (monsterVo.HurtDownResist >= 100) { /* * * meController.StatuController.SetStatu(Status.HURT4);*/ SetHurt4(actionVo); meController.GetMeVo().HurtDownResist = (uint)monsterVo.MonsterVO.hurt_down_resist; } else { monsterVo.HurtDownResist += 5; /* * if (meController.StatuController.CurrentStatu == Status.HURT1) * { * meController.StatuController.SetStatu(Status.HURT2); * } * else * { * meController.StatuController.SetStatu(Status.HURT1); * }*/ meController.StatuController.SetStatu(Status.HURT1); } break; } }
public override void Update() { //下面处理箭头指示 BossDirectionTip(); //处理怪物位置的提示 if (AppMap.Instance.me == null || AppMap.Instance.me.Controller == null) { return; } if (_meAiController == null) { _meAiController = AppMap.Instance.me.Controller.AiController as MeAiController; } //CD显示 float[] cdTimes = AppMap.Instance.me.Controller.SkillController.LeftCdTimes; float[] totalTimes = AppMap.Instance.me.Controller.SkillController.TotalCdTimes; int[] skillMpCost = AppMap.Instance.me.Controller.SkillController.SkillMpCost; _skill1Cd.GetComponent <UISprite>().fillAmount = cdTimes[SkillController.Skill1] / totalTimes[SkillController.Skill1]; _skill2Cd.GetComponent <UISprite>().fillAmount = cdTimes[SkillController.Skill2] / totalTimes[SkillController.Skill2]; _skill3Cd.GetComponent <UISprite>().fillAmount = cdTimes[SkillController.Skill3] / totalTimes[SkillController.Skill3]; _skill4Cd.GetComponent <UISprite>().fillAmount = cdTimes[SkillController.Skill4] / totalTimes[SkillController.Skill4]; _skill0Cd.GetComponent <UISprite>().fillAmount = cdTimes[SkillController.Roll] / totalTimes[SkillController.Roll]; for (int i = 0; i < 5; i++) { if (cdTimes[i + 4] > totalTimes[i + 4] - 0.2 && totalTimes[i + 4] > 0) { _isIncd[i] = true; } if (_isIncd[i] && cdTimes[i + 4] <= 0) { _isIncd[i] = false; //显示技能CD EffectMgr.Instance.CreateUIEffect(EffectId.UI_SkillIcon, _skillCdGameObjects[i].transform.position); } if (cdTimes[i + 4] > 0) { _skillCdTimeLabels[i].gameObject.SetActive(true); _skillCdTimeLabels[i].text = (int)(cdTimes[i + 4] + 1) + ""; } else { _skillCdGameObjects[i].GetComponent <UISprite>().fillAmount = skillMpCost[i + 4] > MeVo.instance.CurMp ? 1 : 0; _skillCdTimeLabels[i].gameObject.SetActive(false); } } Vector2 position = _nguiJoystick.position; if (position.x > 0 || position.y > 0 || position.x < 0 || position.y < 0) { var playerControler = AppMap.Instance.me.Controller as PlayerControler; if (playerControler != null) { int dir = Directions.GetDirByVector2(position); playerControler.MoveByDir(dir); _joystickHighLight.spriteName = "Joystick2"; } if (position.x > 0.8f) { if (_guideJoy.activeInHierarchy) { _guideJoy.SetActive(false); //移除指引 _guideSkill.SetActive(true); _guideSkillIndex = 0; ProcessSkillGuide(); } } } else { _joystickHighLight.spriteName = "Joystick1"; } if (_isAttack) { if (Time.time - _lastAttackCommandTime > 0.12f && MeVo.instance.CurHp > 0) { var vo = new ActionVo { ActionType = Actions.ATTACK }; if (_meAiController != null) { _meAiController.SetAi(false); } AppMap.Instance.me.Controller.AttackController.AddAttackList(vo); _lastAttackCommandTime = Time.time; } } }
/// <summary> /// 延迟delay秒进行攻击,弱化AI /// </summary> /// <param name="delay">攻击之间的间隔</param> /// <param name="toActionVo">攻击行为VO</param> /// <returns></returns> private IEnumerator YieldSecordsAutoAttack(float delay, ActionVo toActionVo) { yield return(new WaitForSeconds(delay)); MeController.AttackController.AddAttackList(toActionVo); }
/// <summary> /// 执行器(每帧执行) /// </summary> private void Update() { // 获取animator的信息并根据animator信息进行相应的业务处理 if (_animator == null) { _animator = MeController.Me.Animator; return; } //1. 如果有AI任务或者AI不在待机状态或者死亡的情况下,则不往下走,节省性能消耗 if (!CanUseAi()) { if (!DangJiTester.role_use_ai) // 根据该变得来设置主角是是否使用AI { return; } } //2. 找到最近的敌人 ActionDisplay nearestEnemy = FindNearestEnemyInMapRange(); //3. 如果没有敌人,则在场景内左右移动 if (nearestEnemy == null) { AiMoveBehaviourNoEnemy(); return; } //如果自动切图阶段,则不执行后面的AI if (MapMode.StartAutoMove) { return; } //4. 尝试使用技能 TryToUseSkill(nearestEnemy); //5. 判断最近敌人和AI的Y值差,若Y值差大于0.5个Unity单位,则纵向移动到同一Y值 if (Mathf.Abs(nearestEnemy.Controller.transform.position.y - _meTransform.position.y) > 0.5f) { MoveToTheSameYWithEnemy(nearestEnemy); return; } float disX = Mathf.Abs(nearestEnemy.Controller.transform.position.x - _meTransform.position.x); //6. 若AI和最近敌人的距离大于6个Unity单位,则横向移动到离敌人的6个单位内 if (disX >= 6) { MoveToAttackRange(nearestEnemy); return; } //7. 若在瞬移范围内,则使用瞬移 if ((disX < 6 && disX > 5) || (disX < 2.5f && disX > 1.8f)) { if (MeController.SkillController.LearnedSkillList[SkillController.Roll] != 0 && MeController.SkillController.IsSkillCdReady(SkillController.Roll)) { MeController.SkillController.RequestUseSkill(SkillController.Roll); return; } } //8. 若在普通攻击范围内,则使用普通攻击 if (disX < _normalAttackRange && _mePlayerVo.CurHp > 0) { if (_meTransform.position.x < nearestEnemy.GoBase.transform.position.x) { MeController.Me.ChangeDire(Directions.Right); } else { MeController.Me.ChangeDire(Directions.Left); } var attackVo = new ActionVo { ActionType = Actions.ATTACK, TargetPoint = nearestEnemy.GoBase.transform.position }; StartCoroutine(YieldSecordsAutoAttack(0.5f, attackVo)); return; } //10. 若以上情况都不是,则继续移动到攻击范围内 MoveToAttackRange(nearestEnemy); }
/// <summary> /// AI巡逻行为 a 主要是:ActionType = Actions.RUN , MeController.AttackController.AddAttackList(actionVo); /// 函数功能:使怪物靠近 主角: /// 1. 在attack2攻击范围‘外’,则向主角方向移动 searchLength 距离 /// 2. 主角在attack1攻击范围‘外’,attack2‘内,则 移动 searchLength 或 -= attackRange1,看概率 /// 3. 主角在attack1攻击范围‘内’ /// </summary> private void AiSearchBehaviour() { if (_meEnemyVo == null || _meEnemyVo.MonsterVO.searchLength == 0) { return; } Vector3 point = AppMap.Instance.me.GoBase.transform.position; // 主角位置 float attackRange1 = _meEnemyVo.MonsterVO.sight_range * 0.001f - 0.1f; // sight_range; 攻击范围 float attackRange2 = 2 * _meEnemyVo.MonsterVO.sight_range * 0.001f - 0.1f; bool needFellow = false; //if (_selfTransform.position.x < point.x - attackRange1) // 主角在 右边 if (_selfTransform.position.x < point.x) // 主角在 右边, 应该加个 ‘可视范围’ { if (_selfTransform.position.x + _meEnemyVo.MonsterVO.searchLength < point.x - attackRange2) { // 主角在attack2攻击范围‘外’,距离远一点 point.x = MeController.transform.position.x + _meEnemyVo.MonsterVO.searchLength; // 往右走, value:3 } else if (_selfTransform.position.x + _meEnemyVo.MonsterVO.searchLength < point.x - attackRange1) { // 主角在attack1攻击范围‘外’,attack2‘内’,距离近一点 int random = Random.Range(0, 1000); if (random > _meEnemyVo.MonsterVO.attackAccuracy) // attackAccuracy; 攻击精度,如 800 { point.x = _selfTransform.position.x + _meEnemyVo.MonsterVO.searchLength; // 往右走 } else // 这个范围内,怪可以攻击了 { point.x -= attackRange1; } point.y = point.y + Random.Range(-50, 50) * 0.01f; } else // 主角在attack1攻击范围‘内’ { int random = Random.Range(0, 1000); if (random > _meEnemyVo.MonsterVO.attackAccuracy)//攻击精度 { //float x1 = point.x - attackRange1; //float x2 = Mathf.Max(_selfTransform.position.x, point.x - attackRange2); //point.x = Random.Range(x1, x2); point.x = _selfTransform.position.x + _meEnemyVo.MonsterVO.searchLength; // 往右走 } else { point.x -= attackRange1; } point.y = point.y + Random.Range(-50, 50) * 0.01f; } needFellow = true; } //else if (_selfTransform.position.x > point.x + attackRange1) // 主角在 左边 else if (_selfTransform.position.x > point.x) // 主角在 左边 { if (_selfTransform.position.x - _meEnemyVo.MonsterVO.searchLength > point.x + attackRange2) { point.x = _selfTransform.position.x - _meEnemyVo.MonsterVO.searchLength; } else if (_selfTransform.position.x - _meEnemyVo.MonsterVO.searchLength > point.x + attackRange1) { int random = Random.Range(0, 1000); if (random > _meEnemyVo.MonsterVO.attackAccuracy) { point.x = _selfTransform.position.x - _meEnemyVo.MonsterVO.searchLength; } else { point.x += attackRange1; } point.y = point.y + Random.Range(-120, 120) * 0.01f; } else { int random = Random.Range(0, 1000); if (random > _meEnemyVo.MonsterVO.attackAccuracy) { //float x1 = point.x + attackRange1; //float x2 = Mathf.Min(_selfTransform.position.x, point.x + attackRange2); //point.x = Random.Range(x1, x2); point.x = _selfTransform.position.x - _meEnemyVo.MonsterVO.searchLength; } else { point.x += attackRange1; } point.y = point.y + Random.Range(-120, 120) * 0.01f; } needFellow = true; } if (needFellow) { _stopTime = 0; var actionVo = new ActionVo { RunDestination = point, ActionType = Actions.RUN }; MeController.AttackController.AddAttackList(actionVo); } }
/// <summary> /// 处于普通攻击3状态时的状态处理 /// </summary> /// <param name="stateInfo">当前动画状态信息</param> protected void ProcessAttack3State(AnimatorStateInfo stateInfo) { if (CurrentStatu == Status.ATTACK3 && CurrentCombStatu == Status.COMB_1) { CurrentCombStatu = Status.COMB_2; MeControler.SkillController.RequestUseSkill(SkillController.Attack3); } if (stateInfo.normalizedTime > 0.6 && CurrentStatu == Status.ATTACK3) { judgeNormalCombIfLongkey(); if (MeControler.AttackController.AttackList.Count > 0 && MeControler.SkillController.SkillList.Count == 0 && MaxComb > 3) { ActionVo actionVo = MeControler.AttackController.AttackList[0]; if (actionVo.ActionType == Actions.ATTACK) { MeControler.AttackController.AttackList.RemoveAt(0); CurrentCombStatu = Status.COMB_2; //魔剑士职业有投掷,冲刺连招; if (GameConst.JOB_JIAN == MeVo.instance.job) { if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.A)) { SetStatu(Status.ATTACK5); } else if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S)) { SetStatu(Status.ATTACK6); } else { SetStatu(Status.ATTACK4); } } else { SetStatu(Status.ATTACK4); } } else { CurrentCombStatu = Status.COMB_3; SetStatu(Status.IDLE); } } else { CurrentCombStatu = Status.COMB_3; SetStatu(Status.IDLE); //法师三连击语音播放 if (GameConst.JOB_FASHI == MeVo.instance.job) { if (SpeechMgr.Instance.IsMagicSpeech) { SpeechMgr.Instance.PlaySpeech(SpeechConst.MagicNormalSkillCycle); } } } } }
/// <summary> /// 执行动作添加到队列 /// </summary> /// <param name="vo">动作信息</param> /// <param name="isPush">强行插入</param> public virtual void AddAttackList(ActionVo vo, bool isPush = false) { }