using vnxbqy.UI; using UnityEngine; public abstract class GActorNpcFight : GActorFight, IOtherSelectable { protected GameObject m_Model { get; private set; } protected Animator m_Animator { get; private set; } private SFXController m_Shadow; protected DialogueBubble m_DialogAppear; protected DialogueBubble m_DialogTiming; protected float m_LastTalkTime; public NPCConfig NpcConfig { get; protected set; } public NPCExConfig NpcConfigEx { get; protected set; } private SFXController m_AppearEffect; private bool m_LoadDefaultRes = false; protected bool IsUnInit = false; /// /// 上一次记录不能被攻击旋转的时间 /// protected float m_LastCantAtkedTime; public override int NextAction { get { if (!m_Animator || !m_Animator.runtimeAnimatorController) { return -1; } return m_Animator.GetInteger(GAStaticDefine.Param_Action); } set { if (m_Animator && m_Animator.runtimeAnimatorController) { if (m_Animator.parameterCount > 0) { m_Animator.SetInteger(GAStaticDefine.Param_Action, value); } } } } public virtual void InitNpcConfig(int npcID) { if (NpcConfig != null && NpcConfig.NPCID == npcID) { return; } if (npcID > 0) { NpcConfig = NPCConfig.Get(npcID); NpcConfigEx = NPCExConfig.Get(npcID); } } protected override void OnInit(GameNetPackBasic package) { base.OnInit(package); IsUnInit = false; m_LoadDefaultRes = false; int _npcID = 0; if (this is GA_NpcSummonFight) { _npcID = (int)(package as H0408_tagPlayerSummonNPCAppear).NPCID; } else if (this is GA_Pet) { _npcID = (int)(package as H0435_tagPetAppear).NPCID; } else if (this is GA_NpcFightNorm) { _npcID = (int)(package as H0406_tagNPCAppear).NPCID; } InitNpcConfig(_npcID); if (NpcConfig == null) { // 报错 Debug.LogError("配置异常....: " + _npcID); return; } ActorType = GameObjType.gotNPC; Root.gameObject.layer = LayerUtility.Monster; if (NpcConfig.ModeProportion != 1) { Root.localScale = Vector3.one * NpcConfig.ModeProportion; } if (CanBeSelected()) { CapsuleCollider _collider = Root.AddMissingComponent(); _collider.center = new Vector3(0, NpcConfig.ModleHeight * .5f, 0); _collider.radius = NpcConfig.ModelRadius; _collider.height = NpcConfig.ModleHeight; } RequestShadow(); InstanceResourcesLoader.AsyncLoadNpc(NpcConfig.NPCID, OnPrefabLoadFinished); } private void OnPrefabLoadFinished(bool result, UnityEngine.Object prefab) { if (IsUnInit) { return; } if (!result || prefab == null) { if (!m_LoadDefaultRes) { m_LoadDefaultRes = true; if (this is GA_Pet) { InstanceResourcesLoader.AsyncLoadDefaultPet(OnPrefabLoadFinished); } else { InstanceResourcesLoader.AsyncLoadDefaultFightNpc(OnPrefabLoadFinished); } } else { m_LoadDefaultRes = false; Debug.LogErrorFormat("加载Npc模型资源出错: {0}", NpcConfig.NPCID); } return; } if (!(this is GA_Pet)) { GAMgr.Instance.AddNeedDestroyPrefab(prefab as GameObject); } if (m_LoadDefaultRes) { if (this is GA_Pet) { m_Model = GameObjectPoolManager.Instance.RequestDefaultPet(); } else { m_Model = GameObjectPoolManager.Instance.RequestDefaultFightNpc(); } } else { m_Model = GameObjectPoolManager.Instance.RequestGameObject(prefab as GameObject); } if (!m_Model) { return; } OnMainModelLoaded(); bool _playEffect = true; uint _parentSID = ActorInfo.ownerSID; if (_parentSID != PlayerDatas.Instance.PlayerId) { GA_Player _player = GAMgr.Instance.GetBySID(_parentSID) as GA_Player; if (_player != null) { _playEffect = _player.ShowOrHide; } } if (_playEffect) { if (NpcConfig.NPCEffect != 0) { m_AppearEffect = SFXPlayUtility.Instance.PlayBattleEffect(NpcConfig.NPCEffect, this); EffectConfig _effectConfig = EffectConfig.Get(NpcConfig.NPCEffect); if (_effectConfig != null) { SoundPlayer.Instance.PlayAudio(m_AudioSource, _effectConfig.audio); } } } } protected override void OnUnit() { HideEffect(); StatusMgr.Instance.ReleaseActor(ServerInstID); if (!ShowOrHide) { m_Model.transform.localPosition = Vector3.zero; m_Model.transform.localRotation = Quaternion.identity; if (MP_Name != m_Model.transform) { MP_Name.SetParent(m_Model.transform); } if (MP_Hit != m_Model.transform) { MP_Hit.SetParent(m_Model.transform); } if (MP_Stun != m_Model.transform) { MP_Stun.SetParent(m_Model.transform); } } if (m_LoadDefaultRes) { if (this is GA_Pet) { GameObjectPoolManager.Instance.ReleaseDefaultPet(m_Model); } else { GameObjectPoolManager.Instance.ReleaseDefaultFightNPC(m_Model); } } else { GameObject _prefab = InstanceResourcesLoader.LoadNpc(NpcConfig.NPCID); GameObjectPoolManager.Instance.ReleaseGameObject(_prefab, m_Model); } m_Model = null; if (m_Animator) { m_Animator.runtimeAnimatorController = null; NextAction = 0; m_Animator.enabled = false; m_Animator = null; } ReleaseShadow(); ReleaseName(); ReleaseLifeBar(); ReleaseDialogueBubble(); if (m_AppearEffect) { SFXPlayUtility.Instance.Release(m_AppearEffect); m_AppearEffect = null; } IsUnInit = true; base.OnUnit(); } public override void Destroy() { } public sealed override void SetAnimatorSpeed(float speed) { if (m_Animator) { m_Animator.speed = speed; //if (this is GA_NpcSummonFight) //{ // Debug.LogFormat("设置了动画速度: {0}", speed); //} } } public sealed override void Play(int stateNameHash, float normalizeTime = 0) { if (m_Animator) { if (m_Animator.HasState(0, stateNameHash)) { m_Animator.Play(stateNameHash, 0, normalizeTime); } } } public override void Idle() { NextAction = GAStaticDefine.Act_Idle; } public override void Run() { NextAction = GAStaticDefine.Act_Run; } public override void IdleImmediate() { if (m_Animator) { Idle(); if (m_Animator.HasState(0, GAStaticDefine.State_IdleHash)) { m_Animator.Play(GAStaticDefine.State_IdleHash); } //if (this is GA_Pet) //{ // Debug.LogFormat("调用了 {0} 的立即站立", ServerInstID); //} } } public override void RunImmediate() { if (m_Animator) { Run(); m_Animator.Play(GAStaticDefine.State_RunHash); if (this is GA_Pet) { Debug.LogFormat(" ---- 调用了 {0} 的立即跑动", ServerInstID); } } } public override bool IsIdle() { if (m_Animator) { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == GAStaticDefine.State_IdleHash; } return false; } public override bool IsRun() { if (m_Animator) { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == GAStaticDefine.State_RunHash; } return false; } public override bool IsHurt() { if (m_Animator) { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == GAStaticDefine.State_HurtHash; } return false; } public sealed override bool IsStun() { if (m_Animator) { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == GAStaticDefine.State_StunHash; } return false; } public sealed override void Hurt() { if (m_Animator == null) { return; } if (NextAction == GAStaticDefine.Act_Dead || NextAction == GAStaticDefine.Act_Warn) { return; } m_Animator.Play(GAStaticDefine.State_HurtHash); } public sealed override void HurtDown() { if (m_Animator == null) { return; } if (m_Animator.GetInteger(GAStaticDefine.Param_Action) == GAStaticDefine.Act_Dead || m_Animator.GetInteger(GAStaticDefine.Param_Action) == GAStaticDefine.Act_Warn) { return; } m_Animator.Play(GAStaticDefine.State_HurtDown1Hash); } public override void Die() { #if UNITY_EDITOR if (this is GA_NpcClientFightBoss) { Debug.LogFormat("调用了死亡"); } #endif if (m_Animator == null) { ReleaseShadow(); StatusMgr.Instance.ReleaseActor(ServerInstID); GAMgr.Instance.Release(this); return; } if (m_AppearEffect) { var _animNodde = m_AppearEffect.GetComponent("Animation"); if (_animNodde) { if (_animNodde.HasState(0, GAStaticDefine.State_DeadHash)) { _animNodde.Play(GAStaticDefine.State_DeadHash); } } } if (NextAction == GAStaticDefine.Act_Dead) { return; } if (OnDie != null) { OnDie(); } ReleaseDialogueBubble(); if (PlayerDatas.Instance.hero != null) { if (PlayerDatas.Instance.hero.LockTarget == this) { PlayerDatas.Instance.hero.LockTarget = null; } if (PlayerDatas.Instance.hero.SelectTarget == this) { PlayerDatas.Instance.hero.SelectTarget = null; } } ReleaseShadow(); StatusMgr.Instance.ReleaseActor(ServerInstID); NextAction = GAStaticDefine.Act_Dead; Play(GAStaticDefine.State_DeadHash); Dead_4 _dead = m_Animator.GetBehaviour(); if (_dead) { _dead.killServerInstID = KillerServerInstID; _dead.killerPos = KillerPos; _dead.killHurtType = killHurtType; } if (this is GA_NpcClientFightBoss || this is GA_NpcFightBoss) { if (m_AudioSource) { if (NpcConfig.Sounds != null) { if (NpcConfig.Sounds.Length > 2) { SoundPlayer.Instance.PlayAudio(m_AudioSource, NpcConfig.Sounds[2]); } } } } #if UNITY_EDITOR string _content = string.Format("调用了 SID: {0}, CID: {1} 的Die方法 ", ServerInstID, ClientInstID); RuntimeLogUtility.AddLog_Red(_content, ServerInstID); #endif } public override void RequestShadow() { ReleaseShadow(); m_Shadow = SFXPlayUtility.Instance.PlayBattleEffect(999999, m_Root); m_Shadow.duration = 0; m_Shadow.transform.localScale = new Vector3((NpcConfig.ModelRadius * 2) / Root.transform.localScale.x, 1, (NpcConfig.ModelRadius * 2) / Root.transform.localScale.z); } public sealed override void ReleaseShadow() { if (m_Shadow) { SFXPlayUtility.Instance.Release(m_Shadow); m_Shadow = null; } } public sealed override bool HasState(int stateHash) { if (m_Animator) { return m_Animator.HasState(0, stateHash); } return false; } public abstract void RequestDialogueBubble(); protected abstract void UpdateTimeDialogueBubble(); public void ReleaseDialogueBubble() { if (m_DialogAppear != null) { NPCDialogueBubble.Recyle(m_DialogAppear); m_DialogAppear = null; } if (m_DialogTiming != null) { NPCDialogueBubble.Recyle(m_DialogTiming); m_DialogTiming = null; } } public override abstract void RequestName(); public override abstract void RequestLifeBar(); public abstract bool CanBeSelected(); public abstract void OnSelect(); public abstract void OnUnSelect(); public abstract void OnClick(); protected virtual void OnMainModelLoaded() { SkinnedMeshRenderer _renderer = m_Model.GetComponentInChildren(); if (_renderer) { _renderer.gameObject.layer = LayerUtility.Monster; m_Material = _renderer.material; } m_Animator = m_Model.GetComponent(); if (!m_Animator) { if (m_Model.transform.childCount > 0) { m_Animator = m_Model.transform.GetChild(0).GetComponent(); } } if (m_Animator) { RuntimeAnimatorController _controller = null; if (m_LoadDefaultRes) { if (this is GA_Pet) { _controller = AnimatorControllerLoader.LoadDefaultMobAnimatorController_Pet(); } else { _controller = AnimatorControllerLoader.LoadDefaultMobAnimatorController_Fight(); } } else { _controller = AnimatorControllerLoader.LoadMobController(AnimatorControllerLoader.controllerSuffix, NpcConfig.MODE); } if (_controller) { m_Animator.runtimeAnimatorController = _controller; } m_Animator.enabled = true; if (m_Animator.parameterCount > 0) { m_Animator.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID); } IdleImmediate(); } SetupBindNode(m_Model.transform); m_Model.transform.SetParent(m_Root.transform); m_Model.transform.localPosition = Vector3.zero; m_Model.transform.localRotation = Quaternion.identity; m_Model.transform.localScale = Vector3.one; GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero.SelectTarget == this) { RequestName(); RequestLifeBar(); } } /// /// 显示或者隐藏表现层 /// /// 显示: true, 隐藏: false public override void ShowOrHideModel(bool showOrHide) { if (ShowOrHide == showOrHide) { return; } if (showOrHide) { if (m_Model) { m_Model.transform.localPosition = Vector3.zero; m_Model.transform.localRotation = Quaternion.identity; GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero != null && _hero.SelectTarget == this) { RequestLifeBar(); } if (MP_Name != m_Model.transform) { MP_Name.SetParent(m_Model.transform); } if (MP_Hit != m_Model.transform) { MP_Hit.SetParent(m_Model.transform); } if (MP_Stun != m_Model.transform) { MP_Stun.SetParent(m_Model.transform); } } RequestShadow(); } else { if (MP_Name && MP_Name != m_Model.transform) { MP_Name.SetParent(Root); } if (MP_Hit && MP_Hit != m_Model.transform) { MP_Hit.SetParent(Root); } if (MP_Stun && MP_Stun != m_Model.transform) { MP_Stun.SetParent(Root); } if (m_Model) { m_Model.transform.localPosition = Constants.Special_Hide_Position; } ReleaseShadow(); } ShowOrHide = showOrHide; } public void CastSkill(int skillID) { Vector3 _dir = (PlayerDatas.Instance.hero.Pos - Pos).normalized; _dir.y = 0; Forward = _dir; Skill _skill = SkillMgr.Get(skillID); if (_skill.IsValid() == false) { return; } SkillMgr.CastSkill(ServerInstID, skillID); if (_skill.skillInfo.config.CastTime != 0) { Warn_300 _warn300 = m_Animator.GetBehaviour(); if (_warn300) { _warn300.nextSkillID = _skill.id; } m_Animator.speed = 2 / (_skill.skillInfo.config.CastTime * Constants.F_GAMMA); NextAction = 300; m_Animator.Play(GAStaticDefine.State_WarnHash); int _type; int _effectID = -1; SFXController _sfxController = null; WarnEffectController _warnEffectController = null; if (_skill.skillInfo.config.WarnInfo > 99) { _type = _skill.skillInfo.config.WarnInfo / 1000000; _effectID = _skill.skillInfo.config.WarnInfo % 1000000; } else { _type = _skill.skillInfo.config.WarnInfo; } if (_effectID != -1) { _sfxController = SFXPlayUtility.Instance.Play(_effectID, Pos, Vector3.forward); _warnEffectController = _sfxController.GetComponent(); _warnEffectController.Init(10009, _skill.skillInfo.config.CastTime, _skill.skillInfo.config.CastTime); if (_type == 100 || _type == 310) { _warnEffectController.CalculateScale(E_HitTestType.Sector, 1, _skill.skillInfo.config.AtkDist); } else if (_type > 200 && _type < 300) { _warnEffectController.transform.position = Pos; float width = _type % 10; float length = (_type % 100) / 10; SkillHelper.EffectValue _effectValue; if (_skill.skillInfo.effectValue.TryGetValue(2100, out _effectValue)) { length = _effectValue.value1 * .5f; } _dir = MathUtility.ForwardXZ(PlayerDatas.Instance.hero.Pos, Pos); if (_dir == Vector3.zero) { _dir = Forward; } _skill.mainTarget = PlayerDatas.Instance.hero; Vector3 _sourcePos = Pos; _sourcePos.y = 0; Vector3 _targetPos = Pos + Forward * (length * .5f); _targetPos.y = 0; UnityEngine.AI.NavMeshHit _navMeshHit; if (UnityEngine.AI.NavMesh.Raycast(_sourcePos, _targetPos, out _navMeshHit, -1)) { _targetPos = _navMeshHit.position; } _skill.targetPosition = _targetPos; //_skill.targetPosition.y = Pos.y; _warnEffectController.transform.forward = _dir; _warnEffectController.CalculateScale(E_HitTestType.Rect, width, length); } } _skill.SkillPreparing = true; SkillMgr.DoingPrepareSkill = true; } else { if (_skill.skillInfo.config.Skillactmark != 0) { NextAction = _skill.skillInfo.config.Skillactmark; SkillMgr.CastSkill(ServerInstID, skillID); ulong hurtValue = 0; byte attackType = 0; AttackHandler.CalculateDamage(this, PlayerDatas.Instance.hero, _skill, 0, ref hurtValue, ref attackType); if (ClientDungeonStageUtility.isClientDungeon) { // hurtValue = int(dMaxHP*0.01*(1+atkSkillPer/10000.0)) hurtValue = (ulong)Mathf.Ceil(PlayerDatas.Instance.extersion.MaxHP * .01f * (1 + NpcConfig.PoisionAtk * Constants.F_DELTA)); } if (PlayerDatas.Instance.hero.ActorInfo.Hp - hurtValue < 0) { hurtValue = PlayerDatas.Instance.hero.ActorInfo.Hp; } AttackHandler.HurtObjs _hurtObject = new AttackHandler.HurtObjs { AttackType = attackType, clientInstID = PlayerDatas.Instance.hero.ClientInstID, CurHP = PlayerDatas.Instance.hero.ActorInfo.Hp - hurtValue, HurtHP = hurtValue, RealHurtHP = hurtValue, ObjID = PlayerDatas.Instance.hero.ServerInstID, ObjType = (byte)GameObjType.gotPlayer }; _skill.hurtClientList.Add(_hurtObject); } } } public void StartCantAtkedRotate() { m_LastCantAtkedTime = Time.time; } public sealed override void Polymorph(bool doOrNo, int npcID) { IsPolyMorph = doOrNo; var _npcConfig = NPCConfig.Get(npcID); if (IsPolyMorph) { ChangeBinderToRoot(); m_SheepIsDefaultNpc = false; var _p = InstanceResourcesLoader.LoadNpc(npcID); if (_p == null) { _p = InstanceResourcesLoader.LoadDefaultFightNPC(); m_SheepIsDefaultNpc = true; } m_Model.transform.localPosition = Constants.Special_Hide_Position; m_SheepModel = GameObjectPoolManager.Instance.RequestGameObject(_p); m_SheepModel.transform.SetParent(m_Root); var _a = m_SheepModel.GetComponent(); if (_a) { RuntimeAnimatorController _controller = null; if (m_SheepIsDefaultNpc) { _controller = AnimatorControllerLoader.LoadDefaultMobAnimatorController_Fight(); } else { _controller = AnimatorControllerLoader.LoadMobController(AnimatorControllerLoader.controllerSuffix, _npcConfig.MODE); } if (_controller) { _a.runtimeAnimatorController = _controller; } _a.enabled = true; _a.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID); m_Animator.enabled = false; m_Animator = _a; } if (ShowOrHide) { m_SheepModel.transform.localPosition = Vector3.zero; } else { m_SheepModel.transform.localPosition = Constants.Special_Hide_Position; } m_SheepModel.transform.localRotation = Quaternion.identity; } else { if (m_SheepModel) { var _a = m_SheepModel.GetComponent(); if (_a) { _a.enabled = false; _a.runtimeAnimatorController = null; } if (m_SheepIsDefaultNpc) { GameObjectPoolManager.Instance.ReleaseDefaultFightNPC(m_SheepModel); } else { var _prefab = InstanceResourcesLoader.LoadNpc(npcID); GameObjectPoolManager.Instance.ReleaseGameObject(_prefab, m_SheepModel); } } m_SheepModel = null; m_Model.transform.localPosition = Vector3.zero; ChangeBinderToClothes(); m_Animator = m_Model.GetComponent(); m_Animator.enabled = true; m_Animator.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID); m_Animator.SetInteger(GAStaticDefine.Param_MoveState, (int)E_MovingState.Normal); } } protected sealed override void ChangeBinderToRoot() { if (MP_Name != m_Model.transform) { MP_Name.SetParent(Root); } if (MP_Hit != m_Model.transform) { MP_Hit.SetParent(Root); } if (MP_Stun != m_Model.transform) { MP_Stun.SetParent(Root); } } protected sealed override void ChangeBinderToClothes() { if (MP_Name != m_Model.transform) { MP_Name.SetParent(m_Model.transform); } if (MP_Hit != m_Model.transform) { MP_Hit.SetParent(m_Model.transform); } if (MP_Stun != m_Model.transform) { MP_Stun.SetParent(m_Model.transform); } } }