using Snxxz.UI; using UnityEngine; using System.Collections.Generic; public class GA_NpcClientFightNorm : GActorNpcFight { private ProcessManager m_ProcessManager; public UnityEngine.Events.UnityAction OnAttackObj; public UnityEngine.Events.UnityAction OnBeAttack; public void AttackObj(uint sid, int skillId) { if (OnAttackObj != null) { OnAttackObj(sid, skillId); } } public void BeAttack(uint sid, int skillId) { if (OnBeAttack != null) { OnBeAttack(sid, skillId); } } public float lockHp { get; private set; } public void LockHp(float per) { lockHp = per; } public bool lockCommonAtk = false; public int lockSkillID = -1; public Dictionary ProcessEffectDict = new Dictionary(); public void AutoAI() { lockCommonAtk = false; lockSkillID = -1; } public bool isTalking = false; public bool isStopAI = false; private HeadUpName m_HeadUpName; private LifeBar m_LifeBar; private uint m_LockTargetSID; public uint LockTargetSID { get { return m_LockTargetSID; } set { m_LockTargetSID = value; } } // 用于触发点击的组件 private NPCInteractProcessor m_NPCInteractProcessor; public override Vector3 BornPos { get { return base.BornPos; } set { base.BornPos = value; if (m_AIHandler != null) { m_AIHandler.BornPos = value; } if (m_Obstacle) { m_Obstacle.transform.position = new Vector3(value.x, 0, value.z); m_Obstacle.transform.eulerAngles = Root.eulerAngles; } } } private UnityEngine.AI.NavMeshObstacle m_Obstacle; protected SampleAI m_AIHandler; /// /// 是否被英雄攻击了 /// public bool heroAttacked; public int posIndex = -1; public UnityEngine.Events.UnityAction OnAttacked; public void BeAttacked() { if (OnAttacked != null) { OnAttacked(); } heroAttacked = true; } protected override void OnInit(GameNetPackBasic package) { base.OnInit(package); // 可选择对象创建碰撞区 if (CanBeSelected()) { m_NPCInteractProcessor = Root.AddMissingComponent(); m_NPCInteractProcessor.npcIntergactEvent += OnClick; } // 初始化基本属性 ActorInfo.Hp = (uint)NpcConfig.DHP; ActorInfo.HpEx = (uint)NpcConfig.MaxHPEx; ActorInfo.MaxHp = (uint)NpcConfig.DHP; ActorInfo.MaxHpEx = (uint)NpcConfig.MaxHPEx; if (NpcConfig.OrgSpeed != 0) { ActorInfo.moveSpeed = 1000 / NpcConfig.OrgSpeed * .5f; } ActorInfo.PlayerName = NpcConfig.charName; ActorInfo.LV = (ushort)NpcConfig.NPCLV; // 战斗类型的怪物随机朝向 Rotation = Quaternion.Euler(0, UnityEngine.Random.Range(0, 360), 0); lockHp = 0; isTalking = false; isStopAI = false; heroAttacked = false; AutoAI(); if (m_ProcessManager == null) { m_ProcessManager = new ProcessManager(); } m_ProcessManager.Load(this); InitAI(); } protected virtual void InitAI() { if (NpcConfig.AIType == 1) { m_AIHandler = new AI_Npc_200(this, BornPos); } else if (NpcConfig.AIType == 198) { m_AIHandler = new AI_Npc_198(this, BornPos); } } public override void OnClick() { if (ActorInfo.serverDie || BossShowModel.Instance.BossShowing) { return; } GA_Hero _hero = PlayerDatas.Instance.hero; if (!PathFinder.WalkAble(_hero.Pos, Pos)) { return; } // 当前锁定的目标已经是此对象 if (_hero.LockTarget == this) { // 开启攻击至死AI } else { // 设置锁定目标为此对象 _hero.LockTarget = this; _hero.SelectTarget = this; } } protected override void OnMainModelLoaded() { base.OnMainModelLoaded(); if (NpcConfig.NPCID == 1002) { m_Obstacle = SoMap.CreateImpasse.General(Pos, Root.eulerAngles, new Vector3(3, 10, 1)); #if UNITY_EDITOR m_Obstacle.name = string.Format("Obstacle_{0}_{1}", ServerInstID, NpcConfig.NPCID); #endif } } protected override void OnUnit() { if (m_NPCInteractProcessor) { m_NPCInteractProcessor.npcIntergactEvent -= OnClick; m_NPCInteractProcessor = null; } if (m_ProcessManager != null) { m_ProcessManager.UnLoad(); } if (m_AIHandler != null) { m_AIHandler.UnInit(); m_AIHandler = null; } if (m_Obstacle) { Object.Destroy(m_Obstacle.gameObject); m_Obstacle = null; } belongEventID = -1; if (posIndex != -1) { HeroRoundGird.Instance.Release(posIndex); posIndex = -1; } foreach (var _sfx in ProcessEffectDict.Values) { SFXPlayUtility.Instance.Release(_sfx); } ProcessEffectDict.Clear(); base.OnUnit(); } protected override void OnFixedUpdate() { base.OnFixedUpdate(); if (!ActorInfo.serverDie) { UpdateTimeDialogueBubble(); } } protected override void OnLateUpdate() { } protected override void OnUpdate() { base.OnUpdate(); if (ActorInfo.serverDie || ActorInfo.RealHp == 0) { return; } if (m_ProcessManager != null) { m_ProcessManager.Update(); } if (m_AIHandler != null) { m_AIHandler.Update(); } } public virtual void SyncHp() { if (m_LifeBar != null) { m_LifeBar.Show(ActorInfo.RealHp, ActorInfo.RealMaxHp); } } public override void Die() { if (m_Obstacle) { Object.Destroy(m_Obstacle.gameObject); m_Obstacle = null; } base.Die(); } public bool IsState(int stateHash) { if (m_Animator) { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == stateHash; } return false; } public override void RequestLifeBar() { ReleaseLifeBar(); m_LifeBar = LifeBar.RequireLifeBar(MP_Name, 0, CameraController.Instance.CameraObject); } public override void RefreshLifeBar(ulong value) { if (m_LifeBar) { m_LifeBar.Show(ActorInfo.RealHp, ActorInfo.RealMaxHp); } } public override void ReleaseLifeBar() { if (m_LifeBar != null) { m_LifeBar.target = null; m_LifeBar.neverHide = false; LifeBar.Recycle(m_LifeBar); m_LifeBar = null; } } public override void ReleaseName() { if (m_HeadUpName != null) { m_HeadUpName.target = null; HeadUpName.Recycle(m_HeadUpName); m_HeadUpName = null; } } public override void RequestName() { ReleaseName(); HeadUpName.Pattern _pattern = HeadUpName.Pattern.Monster; m_HeadUpName = HeadUpName.RequireHeadUpName(_pattern, MP_Name, 0, CameraController.Instance.CameraObject); m_HeadUpName.SetMonsterInfo(NpcConfig.NPCID, NpcConfig.NPCLV); } public override void RequestDialogueBubble() { if (m_DialogAppear) { NPCDialogueBubble.Recyle(m_DialogAppear); } } protected override void UpdateTimeDialogueBubble() { // 瞎BB逻辑 if (Time.realtimeSinceStartup - m_LastTalkTime > 5) { if (m_DialogTiming != null) { NPCDialogueBubble.Recyle(m_DialogTiming); } m_DialogTiming = NPCDialogueBubble.TimingShow(NpcConfig.NPCID, MP_Name, CameraController.Instance.CameraObject); m_LastTalkTime = Time.realtimeSinceStartup; } } public override bool CanBeSelected() { return NpcConfig.NPCType != (int)E_NpcType.BreakableObj && NpcConfig.Country != 1 && NpcConfig.NPCType != (int)E_NpcType.Ghost; } public override void OnSelect() { SelectionManager.Request(SelectionManager.E_Type.Red, this, (NpcConfig.ModelRadius * 2) / Root.transform.localScale.x); RequestName(); RequestLifeBar(); } public override void OnUnSelect() { SelectionManager.Release(SelectionManager.E_Type.Red); if (!ActorInfo.serverDie) { ReleaseName(); ReleaseLifeBar(); } } public override bool CanPushedBack() { return NpcConfig.weight != 0 && (IsHurt() || IsIdle()); } public override bool CanHurted() { return NpcConfig.hurtFeedback == 1 && (IsIdle() || IsHurt() || IsRun()) && !SkillMgr.DoingPrepareSkill && (SkillMgr.CurCastSkill == null || SkillMgr.CurCastSkill.SkillCompelete); } public override bool CanDieFly() { return NpcConfig.NPCType != (int)E_NpcType.BreakableObj; } public override bool CanAtked() { // 判断是否相同阵营 bool _sameFaction = NpcConfig.Country != 0 && NpcConfig.Country == PlayerDatas.Instance.baseData.faction; return !_sameFaction && NpcConfig.NPCType != (int)E_NpcType.Func && NpcConfig.NPCType != (int)E_NpcType.Collect && NpcConfig.NPCType != (int)E_NpcType.Pet && !ActorInfo.serverDie && !IsState(GAStaticDefine.State_Open); } public override bool CanAtkedRotate() { return NpcConfig.NPCType != (int)E_NpcType.BreakableObj && NpcConfig.AIType != 201 && !IsRun() && !SkillMgr.DoingPrepareSkill && (SkillMgr.CurCastSkill == null || SkillMgr.CurCastSkill.SkillCompelete) && (Time.time - m_LastCantAtkedTime > NpcConfig.AtkInterval * Constants.F_GAMMA + 1f); } }