/// <summary> 获取角色攻击状态 </summary> /// <param name="type">攻击类型</param> /// <param name="index">索引</param> /// <returns></returns> public static RoleAnimatorState GetRoleAnimatorState(RoleAttackType type, int index) { if (m_AttackStateDic == null) { m_AttackStateDic = new Dictionary <string, RoleAnimatorState>(); m_AttackStateDic["PhyAttack1"] = RoleAnimatorState.PhyAttack1; m_AttackStateDic["PhyAttack2"] = RoleAnimatorState.PhyAttack2; m_AttackStateDic["PhyAttack3"] = RoleAnimatorState.PhyAttack3; m_AttackStateDic["PhyAttack4"] = RoleAnimatorState.PhyAttack4; m_AttackStateDic["Skill1"] = RoleAnimatorState.Skill1; m_AttackStateDic["Skill2"] = RoleAnimatorState.Skill2; m_AttackStateDic["Skill3"] = RoleAnimatorState.Skill3; m_AttackStateDic["Skill4"] = RoleAnimatorState.Skill4; m_AttackStateDic["Skill5"] = RoleAnimatorState.Skill5; m_AttackStateDic["Skill6"] = RoleAnimatorState.Skill6; m_AttackStateDic["Skill7"] = RoleAnimatorState.Skill7; m_AttackStateDic["Skill8"] = RoleAnimatorState.Skill8; } string key = string.Format("{0}{1}", type == RoleAttackType.PhyAttack ? "PhyAttack" : "Skill", index); if (m_AttackStateDic.ContainsKey(key)) { return(m_AttackStateDic[key]); } return(RoleAnimatorState.PhyAttack1); }
private RoleAttackInfo GetRoleAttackInfo(RoleAttackType type, int skillId) { if (type == RoleAttackType.PhyAttack) { for (int i = 0; i < PhyAttackInfoList.Count; i++) { if (PhyAttackInfoList[i].SkillId == skillId) { return(PhyAttackInfoList[i]); } } } else { for (int i = 0; i < SkillAttackInfoList.Count; i++) { if (SkillAttackInfoList[i].SkillId == skillId) { return(SkillAttackInfoList[i]); } } } return(null); }
public void DoAI() { //当前玩家不存在 if (GlobalInit.Instance == null || GlobalInit.Instance.CurrPlayer == null) { return; } //怪已死亡 if (CurrRole.CurrRoleFSMMgr.CurrRoleStateEnum == RoleState.Die || CurrRole.IsRigidity) { return; } if (CurrRole.LockEnemy == null) { //没有锁定敌人 //如果是待机状态 if (CurrRole.CurrRoleFSMMgr.CurrRoleStateEnum == RoleState.Idle) { if (Time.time > m_NextPatrolTime) { m_NextPatrolTime = Time.time + UnityEngine.Random.Range(5f, 10f); m_MoveToPos = new Vector3(CurrRole.BornPoint.x + UnityEngine.Random.Range(CurrRole.PatrolRadius * -1, CurrRole.PatrolRadius), CurrRole.BornPoint.y, CurrRole.BornPoint.z + UnityEngine.Random.Range(CurrRole.PatrolRadius * -1, CurrRole.PatrolRadius)); m_RayPoint = new Vector3(m_MoveToPos.x, m_MoveToPos.y + 50, m_MoveToPos.z); if (Physics.Raycast(m_RayPoint, new Vector3(0, -100, 0), out m_HitInfo, 1000f, 1 << LayerMask.NameToLayer("RegionMask"))) { return; } //进行巡逻 CurrRole.MoveTo(m_MoveToPos); } } //如果主角在怪的视野范围内 if (Vector3.Distance(CurrRole.transform.position, GlobalInit.Instance.CurrPlayer.transform.position) <= CurrRole.ViewRadius) { //((RoleInfoMonster)CurrRole.CurrRoleInfo).MonsterEntity; CurrRole.LockEnemy = GlobalInit.Instance.CurrPlayer; m_NextAttackTime = Time.time + m_Info.MonsterEntity.DelaySecAttack; } } else { //锁定敌人已死亡 if (CurrRole.LockEnemy.CurrRoleInfo.CurrHP <= 0) { CurrRole.LockEnemy = null; return; } if (Time.time > m_NextThinkTime + UnityEngine.Random.Range(3, 3.5f)) { //让角色休息 CurrRole.ToIdle(RoleIdleState.IdleFight); m_NextThinkTime = Time.time; m_IsDaze = true; } if (m_IsDaze) { //如果角色休息中 if (Time.time > m_NextThinkTime + UnityEngine.Random.Range(1, 1.5f)) { m_IsDaze = false; } else { return; } } //Debug.Log(CurrRole.CurrRoleFSMMgr.CurrRoleStateEnum.ToString()); if (CurrRole.CurrRoleFSMMgr.CurrRoleStateEnum != RoleState.Idle) { return; } //如果有锁定敌人 //1.如果怪和锁定敌人的距离 超过了怪的视野范围 则取消锁定 //主角的速度比怪的速度快 超出怪的视野范围则取消锁定 if (Vector3.Distance(CurrRole.transform.position, GlobalInit.Instance.CurrPlayer.transform.position) > CurrRole.ViewRadius) { CurrRole.LockEnemy = null; return; } //有锁定敌人 并且在可攻击范围之内 if (m_Info.MonsterEntity.PhyAttackPro >= UnityEngine.Random.Range(0, 100)) { //使用物理攻击 m_UsedSkillId = m_Info.MonsterEntity.PhyAttackIdArray[UnityEngine.Random.Range(0, m_Info.MonsterEntity.PhyAttackIdArray.Length)]; m_RoleAttackType = RoleAttackType.PhyAttack; } else { //使用技能攻击 m_UsedSkillId = m_Info.MonsterEntity.SkillAttackIdArray[UnityEngine.Random.Range(0, m_Info.MonsterEntity.SkillAttackIdArray.Length)]; m_RoleAttackType = RoleAttackType.SkillAttack; } SkillEntity entity = SkillDBModel.Instance.Get(m_UsedSkillId); if (entity == null) { return; } //2.判断敌人是否在此技能的攻击范围内 if (Vector3.Distance(CurrRole.transform.position, GlobalInit.Instance.CurrPlayer.transform.position) <= entity.AttackRange) { //让怪朝向锁定敌人 CurrRole.transform.LookAt(new Vector3(CurrRole.LockEnemy.transform.position.x, CurrRole.transform.position.y, CurrRole.LockEnemy.transform.position.z)); //攻击 if (Time.time > m_NextAttackTime && CurrRole.CurrRoleFSMMgr.CurrRoleStateEnum != RoleState.Attack) { m_NextAttackTime = Time.time + UnityEngine.Random.Range(0f, 1f) + m_Info.MonsterEntity.DelaySecAttack; CurrRole.ToAttack(m_RoleAttackType, m_UsedSkillId); } } else { //追逐 if (CurrRole.CurrRoleFSMMgr.CurrRoleStateEnum == RoleState.Idle) { m_MoveToPos = GameUtil.GetRandomPos(CurrRole.transform.position, CurrRole.LockEnemy.transform.position, entity.AttackRange); m_RayPoint = new Vector3(m_MoveToPos.x, m_MoveToPos.y + 50, m_MoveToPos.z); if (Physics.Raycast(m_RayPoint, new Vector3(0, -100, 0), out m_HitInfo, 1000f, 1 << LayerMask.NameToLayer("RegionMask"))) { return; } CurrRole.MoveTo(m_MoveToPos); } } } }
/// <summary> 发起攻击 </summary> /// <param name="type">攻击类型</param> /// <param name="skillId">技能Id</param> public void ToAttack(RoleAttackType type, int skillId) { Attack.ToAttack(type, skillId); }
public void ToAttack(RoleAttackType type, int skillId) { if (m_CurrRoleFSMMgr == null || m_CurrRoleFSMMgr.CurrRoleCtrl.IsRigidity) { if (type == RoleAttackType.SkillAttack) { m_NextSkillId = skillId; } return; } m_NextSkillId = -1; //1.角色类型只有玩家和怪才参与技能数值计算 if (m_CurrRoleCtrl.CurrRoleType == RoleType.MainPlayer || m_CurrRoleCtrl.CurrRoleType == RoleType.Monster) { //2.获取技能信息 SkillEntity skillEntity = SkillDBModel.Instance.Get(skillId); if (skillEntity == null) { return; } int skillLevel = m_CurrRoleCtrl.CurrRoleInfo.GetSkillLevel(skillId); //技能所需魔法值 int spendMP = skillEntity.SpendMP + skillEntity.SpendMPLevelUp * (skillLevel - 1); //3.如果是主角 if (m_CurrRoleCtrl.CurrRoleType == RoleType.MainPlayer && type == RoleAttackType.SkillAttack) { if (GlobalInit.Instance.SkillSlotsItem != null) { if (spendMP > GlobalInit.Instance.PlayerInfo.CurrMP) { TipsUtil.ShowTextTips(1000504); return; } GlobalInit.Instance.PlayerInfo.CurrMP -= spendMP; GlobalInit.Instance.PlayerInfo.SetSkillCDEndTime(skillId); if (m_CurrRoleCtrl.OnMPChange != null) { m_CurrRoleCtrl.OnMPChange(ValueChnageType.Reduce); } GlobalInit.Instance.SkillSlotsItem.AddTimer(); GlobalInit.Instance.SkillSlotsItem = null; } } m_EnemyList.Clear(); //4.找敌人 如果是主角才找敌人 怪找敌人使用AI if (m_CurrRoleCtrl.CurrRoleType == RoleType.MainPlayer) { int attackTargetCount = skillEntity.AttackTargetCount; if (attackTargetCount == 1) { #region ------ 单体攻击 ------ //单体攻击 必须有锁定敌人 if (m_CurrRoleCtrl.LockEnemy != null) { m_EnemyList.Add(m_CurrRoleCtrl.LockEnemy); } else { m_SearchList.Clear(); //没有锁定敌人 //发射射线去找 离当前攻击者最近的 就是锁定敌人 Collider[] searchList = Physics.OverlapSphere(m_CurrRoleCtrl.transform.position, skillEntity.AreaAttackRadius, 1 << LayerMask.NameToLayer("Role")); if (searchList != null && searchList.Length > 0) { for (int i = 0; i < searchList.Length; i++) { if (searchList[i].GetComponent <RoleCtrl>().CurrRoleType != RoleType.MainPlayer) { m_SearchList.Add(searchList[i]); } } } m_SearchList.Sort((c1, c2) => { int ret = 0; if (Vector3.Distance(c1.transform.position, m_CurrRoleCtrl.transform.position) < Vector3.Distance(c2.transform.position, m_CurrRoleCtrl.transform.position)) { ret = -1; } else { ret = 1; } return(ret); }); if (m_SearchList.Count > 0) { m_CurrRoleCtrl.LockEnemy = m_SearchList[0].GetComponent <RoleCtrl>(); m_EnemyList.Add(m_CurrRoleCtrl.LockEnemy); } } #endregion } else { #region ------ 群体攻击 ------ int needAttackCount = attackTargetCount; m_SearchList.Clear(); //没有锁定敌人 //发射射线去找 离当前攻击者最近的 就是锁定敌人 Collider[] searchList = Physics.OverlapSphere(m_CurrRoleCtrl.transform.position, skillEntity.AreaAttackRadius, 1 << LayerMask.NameToLayer("Role")); if (searchList != null && searchList.Length > 0) { for (int i = 0; i < searchList.Length; i++) { if (searchList[i].GetComponent <RoleCtrl>().CurrRoleType != RoleType.MainPlayer) { m_SearchList.Add(searchList[i]); } } } m_SearchList.Sort((c1, c2) => { int ret = 0; if (Vector3.Distance(c1.transform.position, m_CurrRoleCtrl.transform.position) < Vector3.Distance(c2.transform.position, m_CurrRoleCtrl.transform.position)) { ret = -1; } else { ret = 1; } return(ret); }); //群体攻击 如果有锁定敌人 锁定敌人必须是攻击目标之一 if (m_CurrRoleCtrl.LockEnemy != null) { m_EnemyList.Add(m_CurrRoleCtrl.LockEnemy); needAttackCount--; for (int i = 0; i < m_SearchList.Count; i++) { RoleCtrl ctrl = m_SearchList[i].GetComponent <RoleCtrl>(); if (ctrl.CurrRoleInfo.RoleId != m_CurrRoleCtrl.CurrRoleInfo.RoleId) { if ((i + 1) > needAttackCount) { break; } m_EnemyList.Add(m_SearchList[i].GetComponent <RoleCtrl>()); } } } else { if (m_SearchList.Count > 0) { m_CurrRoleCtrl.LockEnemy = m_SearchList[0].GetComponent <RoleCtrl>(); for (int i = 0; i < m_SearchList.Count; i++) { RoleCtrl ctrl = m_SearchList[i].GetComponent <RoleCtrl>(); if ((i + 1) > needAttackCount) { break; } m_EnemyList.Add(ctrl); } } } #endregion } } else if (m_CurrRoleCtrl.CurrRoleType == RoleType.Monster) { if (m_CurrRoleCtrl.LockEnemy != null) { m_EnemyList.Add(m_CurrRoleCtrl.LockEnemy); } } //Debug.Log(m_EnemyList.Count); //5.让敌人受伤 for (int i = 0; i < m_EnemyList.Count; i++) { m_EnemyList[i].ToHurt(CalculateHurtValue(m_EnemyList[i], skillEntity)); } } #region ------ 动画特效相关 ------ RoleAttackInfo info = GetRoleAttackInfo(type, skillId); if (info == null) { return; } GlobalInit.Instance.StartCoroutine(PlayerEffect(info)); //EffectManager.Instance.DestroyEffect(trans, info.EffectLifeTime); //if (info.IsDoCameraShake && CameraCtrl.Instance != null) //{ // CameraCtrl.Instance.CameraShake(info.CameraShakeDelay); //} if (m_RoleStateAttack == null) { m_RoleStateAttack = m_CurrRoleFSMMgr.GetRoleState(RoleState.Attack) as RoleStateAttack; } m_RoleStateAttack.AnimatorCondition = type == RoleAttackType.PhyAttack ? "ToPhyAttack" : "ToSkill"; m_RoleStateAttack.AnimatorConditionValue = info.Index; m_RoleStateAttack.AnimatorCurrState = GameUtil.GetRoleAnimatorState(type, info.Index); #endregion m_CurrRoleFSMMgr.ChangeState(RoleState.Attack); }