using UnityEngine; using TableConfig; public abstract class GActorNpcNoFight : GActor, IOtherSelectable { protected GameObject m_Model; protected Animator m_Animator; private UnityEngine.AI.NavMeshObstacle m_Dig; private SFXController m_Shadow; public NPCConfig NpcConfig { get; protected set; } public SFXController m_AppearEffect; protected bool m_LoadDefaultRes = false; public override int NextAction { get { return m_Animator.GetInteger(GAStaticDefine.Param_Action); } set { m_Animator.SetInteger(GAStaticDefine.Param_Action, value); } } protected override void OnInit(GameNetPackBasic package) { m_LoadDefaultRes = false; var _package = package as H0406_tagNPCAppear; if (_package == null) { Debug.LogError("非战斗单位封包传入错误: " + package.GetType()); return; } NpcConfig = Config.Instance.Get((int)_package.NPCID); if (NpcConfig == null) { // 报错 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(); // 这里针对指定的NPC特殊矫正位置 if (GeneralDefine.NpcPosOffset.ContainsKey(NpcConfig.NPCID)) { Pos = GeneralDefine.NpcPosOffset[NpcConfig.NPCID]; } // 执行挖洞逻辑 if (NpcConfig.Dig == 1) { m_Dig = SoMap.CreateImpasse.GeneralCircle(Pos, NpcConfig.ModelRadius); } if (NpcConfig.NPCEffect != 0) { m_AppearEffect = SFXPlayUtility.Instance.PlayBattleEffect(NpcConfig.NPCEffect, this); } // 开始异步加载表现层 InstanceResourcesLoader.AsyncLoadNpc(NpcConfig.NPCID, OnPrefabLoadFinished); } protected override void OnUnit() { if (m_LoadDefaultRes) { GameObjectPoolManager.Instance.ReleaseDefaultFuncNPC(m_Model); } else { if (NpcConfig != null) { GameObject _prefab = InstanceResourcesLoader.LoadNpc(NpcConfig.NPCID); GameObjectPoolManager.Instance.ReleaseGameObject(_prefab, m_Model); } } if (m_AppearEffect) { SFXPlayUtility.Instance.Release(m_AppearEffect); m_AppearEffect = null; } m_Model = null; if (m_Animator) { m_Animator.runtimeAnimatorController = null; m_Animator.enabled = false; m_Animator = null; } ReleaseName(); ReleaseShadow(); if (m_Dig) { Object.Destroy(m_Dig.gameObject); m_Dig = null; } if (Root) { Root.localScale = Vector3.one; } } public override void Destroy() { } protected virtual void OnPrefabLoadFinished(bool result, UnityEngine.Object prefab) { if (!result || prefab == null) { if (!m_LoadDefaultRes) { InstanceResourcesLoader.AsyncLoadDefaultFuncNpc(OnPrefabLoadFinished); m_LoadDefaultRes = true; } else { m_LoadDefaultRes = false; Debug.LogErrorFormat("加载Npc模型资源出错: {0}", NpcConfig.NPCID); } return; } if (PreFightMission.Instance.IsFinished()) { GAMgr.Instance.AddNeedDestroyPrefab(prefab as GameObject); } if (this is GA_Guard || NpcConfig.MODE.Contains("A_Zs") || NpcConfig.MODE.Contains("A_Fs")) { GAMgr.Instance.RemoveNeedDestroyPrefab(prefab as GameObject); } if (m_LoadDefaultRes) { m_Model = GameObjectPoolManager.Instance.RequestDefaultFuncNpc(); } else { m_Model = GameObjectPoolManager.Instance.RequestGameObject(prefab as GameObject); } if (m_Model) { m_Animator = m_Model.GetComponent(); if (m_Animator) { RuntimeAnimatorController _controller = null; if (m_LoadDefaultRes) { _controller = InstanceResourcesLoader.LoadDefaultMobAnimatorController_Func(); } else { string _name = NpcConfig.MODE; if (_name.Contains("A_Zs")) { _name = "A_Zs"; GameObjectPoolManager.Instance.AddDontDestroyGoInstID(m_Model.GetInstanceID()); } else if (_name.Contains("A_Fs")) { _name = "A_Fs"; GameObjectPoolManager.Instance.AddDontDestroyGoInstID(m_Model.GetInstanceID()); } _controller = AnimatorControllerLoader.LoadMobController(AnimatorControllerLoader.controllerSuffix, _name); } if (_controller) { m_Animator.runtimeAnimatorController = _controller; } m_Animator.enabled = true; m_Animator.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID); } SetupBindNode(m_Model.transform); m_Model.transform.SetParent(m_Root); m_Model.transform.localPosition = Vector3.zero; m_Model.transform.localRotation = Quaternion.identity; RequestName(); OnMainModelLoaded(); } } protected virtual void OnMainModelLoaded() { } public virtual void InitPerformance(uint clientInstID, int npcID) { GameObject _prefab = InstanceResourcesLoader.LoadNpcPrefab(npcID); InstanceResourcesLoader.AsyncLoadNpc(npcID, OnPrefabLoadFinished); } public sealed override void SetAnimatorSpeed(float speed) { if (m_Animator) { m_Animator.speed = speed; } } public sealed override void Play(int stateNameHash, float normalizeTime = 0) { if (m_Animator) { m_Animator.Play(stateNameHash, 0, normalizeTime); } } public override void Idle() { NextAction = GAStaticDefine.Act_Idle; } public override void IdleImmediate() { if (m_Animator) { Idle(); m_Animator.Play(GAStaticDefine.State_IdleHash); } } public override void Run() { NextAction = GAStaticDefine.Act_Run; } public override void RunImmediate() { if (m_Animator) { Run(); m_Animator.Play(GAStaticDefine.State_RunHash); } } public override bool IsIdle() { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == GAStaticDefine.State_IdleHash; } public override bool IsRun() { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == GAStaticDefine.State_RunHash; } public override bool IsHurt() { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == GAStaticDefine.State_HurtHash; } public sealed override bool IsStun() { AnimatorStateInfo _stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); return _stateInfo.shortNameHash == GAStaticDefine.State_StunHash; } public sealed override bool HasState(int stateHash) { if (m_Animator) { return m_Animator.HasState(0, stateHash); } return false; } public override void RequestShadow() { ReleaseShadow(); m_Shadow = SFXPlayUtility.Instance.PlayBattleEffect(999999, m_Root); m_Shadow.duration = 0; if (Root.transform.localScale == Vector3.zero) { Root.transform.localScale = Vector3.one; } 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 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; } RequestName(); RequestShadow(); } else { if (m_Model) { m_Model.transform.localPosition = Constants.Special_Hide_Position; } if (PlayerDatas.Instance.hero.SelectTarget == this) { PlayerDatas.Instance.hero.SelectTarget = null; } if (PlayerDatas.Instance.hero.LockTarget == this) { PlayerDatas.Instance.hero.LockTarget = null; } ReleaseName(); ReleaseShadow(); } ShowOrHide = showOrHide; } public override abstract void RequestName(); public override abstract void RequestLifeBar(); public abstract void OnSelect(); public abstract void OnUnSelect(); public abstract bool CanBeSelected(); public abstract void OnClick(); }