using System.Collections; using Snxxz.UI; using TableConfig; using UnityEngine; public class GA_Guard : GActorNpcNoFight { public enum GuardState { Idle, Track, Dance, PickUp, Inter, } #region 配置 public float GuardianSpeed; public float GuardianCanPickupRange; public float GuardianPickupRange; public float GuardianTraceRange; public float GuardianImpendRange; public float GuardianRandomIdleMin; public float GuardianRandomIdleMax; public float GuardianBreakSpeed; public float GuardianHeight; public float GuardianPickFxSpeed; public float GuardianResetRange; public bool GuardianCanPick; #endregion #region 动作Action public static readonly int GuardAction_Idle = 0; public static readonly int GuardAction_Dance1 = 1; public static readonly int GuardAction_Dance2 = 2; public static readonly int GuardAction_Run = 3; #endregion private bool _isStateActive = true; //是否状态机开启 public bool IsStateActive { get { return _isStateActive; } set { _isStateActive = value; } } public float GuardianAnimatorSpeed { get; private set; } public bool isBreakGuardDance { get; set; } PlayerPackModel _playerPack; PlayerPackModel playerPack { get { return _playerPack ?? (_playerPack = ModelCenter.Instance.GetModel()); } } PlayerDeadModel _deadModel; PlayerDeadModel DeadModel { get { return _deadModel ?? (_deadModel = ModelCenter.Instance.GetModel()); } } public GuardState guardState { get; set; } public GActorPlayerBase targetPlayer { get { if (targetPlayerId == PlayerDatas.Instance.PlayerId) { return PlayerDatas.Instance.hero; } else { return GAMgr.Instance.GetBySID((uint)targetPlayerId) as GActorPlayerBase; } } } public int targetPlayerId { get; private set; } TeamModel m_TeamModel; TeamModel teamModel { get { return m_TeamModel ?? (m_TeamModel = ModelCenter.Instance.GetModel()); } } public bool IsControlHero { get { return targetPlayerId == PlayerDatas.Instance.PlayerId; } } public GameObject guardPrefabModel { get; private set; } public int itemID { get; set; } public int[] guardEffects { get; private set; } public GuardPickupItem guardPickupItem { get; private set; } public bool IsPlayerDie { get; private set; } private DungeonOpenTimeConfig dungeonCfg; public sealed override void Die() { } public sealed override void Hurt() { } public sealed override void HurtDown() { } protected sealed override void OnInit(GameNetPackBasic package) { targetPlayerId = (int)(ServerInstID / 100); DeadModel.AllPlayerDieEvent += AllPlayerDieEvent; DeadModel.AllPlayerRebornEvent += AllPlayerRebornEvent; DTC0429_tagObjResetPos.ResetPlayerPosEvent += ResetPlayerPosEvent; if (IsControlHero) { dungeonCfg = ConfigManager.Instance.GetTemplate(PlayerDatas.Instance.baseData.MapID); PlayerDatas.Instance.PlayerDataRefreshInfoEvent += RefreshInfo; StageManager.Instance.onStageLoadFinish += OnStageLoadFinish; } IsPlayerDie = false; if (IsControlHero) { guardPickupItem = Root.AddMissingComponent(); guardPickupItem.guard = this; } else { guardPickupItem = Root.GetComponent(); if (guardPickupItem != null) { Object.DestroyImmediate(guardPickupItem); } } } public void InitBase() { #region 配置 FuncConfigConfig funcCfg = ConfigManager.Instance.GetTemplate("GuardianSpeed"); if (funcCfg != null) { float.TryParse(funcCfg.Numerical1, out GuardianSpeed); float.TryParse(funcCfg.Numerical2, out GuardianBreakSpeed); float.TryParse(funcCfg.Numerical3, out GuardianPickFxSpeed); } funcCfg = ConfigManager.Instance.GetTemplate("GuardianPickupRange"); if (funcCfg != null) { float.TryParse(funcCfg.Numerical1, out GuardianCanPickupRange); float.TryParse(funcCfg.Numerical2, out GuardianPickupRange); } funcCfg = ConfigManager.Instance.GetTemplate("GuardianTraceRange"); if (funcCfg != null) { float.TryParse(funcCfg.Numerical1, out GuardianTraceRange); float.TryParse(funcCfg.Numerical2, out GuardianResetRange); } funcCfg = ConfigManager.Instance.GetTemplate("GuardianImpendRange"); if (funcCfg != null) { float.TryParse(funcCfg.Numerical1, out GuardianImpendRange); } funcCfg = ConfigManager.Instance.GetTemplate("GuardianRandomIdle"); if (funcCfg != null) { float.TryParse(funcCfg.Numerical1, out GuardianRandomIdleMin); float.TryParse(funcCfg.Numerical2, out GuardianRandomIdleMax); } funcCfg = ConfigManager.Instance.GetTemplate("GuardianHigh"); if (funcCfg != null) { float.TryParse(funcCfg.Numerical1, out GuardianHeight); } funcCfg = ConfigManager.Instance.GetTemplate(StringUtility.Contact("SH", itemID)); if (funcCfg != null) { guardEffects = ConfigParse.GetMultipleStr(funcCfg.Numerical3); int _val = 0; int.TryParse(funcCfg.Numerical4, out _val); GuardianCanPick = _val == 1; } #endregion InitializeModelRes(); } protected sealed override void OnUnit() { DeadModel.AllPlayerDieEvent -= AllPlayerDieEvent; DeadModel.AllPlayerRebornEvent -= AllPlayerRebornEvent; DTC0429_tagObjResetPos.ResetPlayerPosEvent -= ResetPlayerPosEvent; if (IsControlHero) { PlayerDatas.Instance.PlayerDataRefreshInfoEvent -= RefreshInfo; StageManager.Instance.onStageLoadFinish -= OnStageLoadFinish; ClearGuardPickupItem(); } if (sfxController != null) { SFXPlayUtility.Instance.Release(sfxController); } if (m_Animator != null) { m_Animator.speed = GuardianAnimatorSpeed; } IsStateActive = false; dungeonCfg = null; guardPickupItem = null; base.OnUnit(); } private void ClearGuardPickupItem() { if (guardPickupItem != null) { guardPickupItem.ClearFx(); } } private void OnStageLoadFinish() { if (m_Model == null) { return; } SnxxzGame.Instance.StartCoroutine(Co_StagePrepare()); } IEnumerator Co_StagePrepare() { yield return null; if (MathUtility.CalDistance(Root.position, targetPlayer.Root.position) > GuardianResetRange * GuardianResetRange) { ResetPos(targetPlayer.Root.position.x, targetPlayer.Root.position.z); } if (sfxController == null || !sfxController.gameObject.activeSelf) { sfxController = SFXPlayUtility.Instance.PlayBattleEffect(guardEffects[0], this, NpcConfig != null ? NpcConfig.ModeProportion : 1); if (sfxController != null) { var mountPoint = Root.GetChildTransformDeeply(GAStaticDefine.MountPointBoneName); sfxController.duration = 0; sfxController.transform.SetParent(mountPoint); sfxController.transform.localPosition = Vector3.zero; } } } private void AllPlayerDieEvent(uint playerID) { if (playerID == targetPlayerId) { IsPlayerDie = true; } } private void AllPlayerRebornEvent(H0419_tagPlayerReborn vNetData) { if (vNetData.PlayerID == targetPlayerId) { IsPlayerDie = false; IsStateActive = true; if (m_Animator) { m_Animator.enabled = true; } ResetPos(vNetData.PosX / 2, vNetData.PosY / 2); } } private void ResetPlayerPosEvent(H0429_tagObjResetPos vNetData) { if (vNetData.ObjID == targetPlayerId) { if (targetPlayer == null) { return; } if (MathUtility.CalDistance(Root.position, targetPlayer.Root.position) > GuardianResetRange * GuardianResetRange) { ResetPos(vNetData.PosX / 2, vNetData.PosY / 2); } } } private void RefreshInfo(PlayerDataRefresh refreshType) { if (refreshType == PlayerDataRefresh.MapID) { dungeonCfg = ConfigManager.Instance.GetTemplate(PlayerDatas.Instance.baseData.MapID); } } public SFXController sfxController = null; private void InitializeModelRes() { IsStateActive = true; m_Model.SetLayer(LayerUtility.Monster, true); var mountPoint = Root.GetChildTransformDeeply(GAStaticDefine.MountPointBoneName); sfxController = SFXPlayUtility.Instance.PlayBattleEffect(guardEffects[0], this, NpcConfig != null ? NpcConfig.ModeProportion : 1); if (sfxController != null) { sfxController.duration = 0; sfxController.transform.SetParent(mountPoint); sfxController.transform.localPosition = Vector3.zero; } m_Animator.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID); m_Animator.enabled = true; GuardianAnimatorSpeed = m_Animator.speed; Idle(); if (IsControlHero) { //GameObject _prefab = InstanceResourcesLoader.LoadNpc(NpcConfig.NPCID); //if (GAMgr.Instance.needDestroyPrefabList.Contains(_prefab)) //{ // GAMgr.Instance.needDestroyPrefabList.Remove(_prefab); //} GameObjectPoolManager.Instance.AddDontDestroyGoInstID(m_Model.GetInstanceID()); } } private void ResetPos(float posx, float posz) { if (targetPlayer == null) { return; } var pos = new Vector3(posx, 0, posz) + targetPlayer.Root.right.normalized * 0.6f - targetPlayer.Forward * 0.3f; pos.y = targetPlayer.Root.position.y + GuardianHeight; if (m_Model) { Root.position = pos; Idle(); } } protected sealed override void OnUpdate() { if (!IsStateActive) { return; } if (targetPlayer == null || m_Model == null) { return; } if (NpcConfig != null && m_Model.transform.localScale.x != NpcConfig.ModeProportion) { m_Model.transform.localScale = new Vector3(NpcConfig.ModeProportion, NpcConfig.ModeProportion, NpcConfig.ModeProportion); } if (CheckPlayerDie()) { return; } CheckDistance(); if (IsControlHero && GuardianCanPick) { if (CheckPickupItem()) { return; } } CheckTrack(); } private void CheckDistance() { var _height = targetPlayer.Root.position.y + GuardianHeight; if (MathUtility.CalDistance(Root.position, targetPlayer.Root.position) > GuardianResetRange * GuardianResetRange) { ResetPos(targetPlayer.Root.position.x, targetPlayer.Root.position.z); } else if (Mathf.Abs(Root.position.y - _height) > 2) { ResetPos(targetPlayer.Root.position.x, targetPlayer.Root.position.z); } } public void Disappear() { IsStateActive = false; ClearGuardPickupItem(); if (m_Model) { Root.position = Constants.Special_Hide_Position; } if (m_Animator) { m_Animator.enabled = false; m_Animator.speed = GuardianAnimatorSpeed; } } public override void Idle() { NextAction = GuardAction_Idle; guardState = GuardState.Idle; } private bool CheckTrack() { if (MathUtility.CalDistance(Root.position, targetPlayer.Root.position) > GuardianTraceRange * GuardianTraceRange && guardState != GuardState.Track) { isBreakGuardDance = true; NextAction = GuardAction_Run; guardState = GuardState.Track; return true; } return false; } private bool CheckPlayerDie() { if (IsPlayerDie) { if (guardState != GuardState.Track && guardState != GuardState.Inter) { isBreakGuardDance = true; guardState = GuardState.Inter; NextAction = GuardAction_Run; } return true; } return false; } public bool CheckPickupItem() { if (dungeonCfg != null) { if (dungeonCfg.GuardPick == 0) return false; } if (DropItemManager.CheckCanGuardPickUp(this)) { if (guardState != GuardState.PickUp) { isBreakGuardDance = true; guardState = GuardState.PickUp; if (NextAction != GuardAction_Run) { NextAction = GuardAction_Run; } else { GuardRun guardRun = m_Animator.GetBehaviour(); guardRun.OnPickUpEnter(); } } return true; } return false; } #region 守护跳舞 private int lastDanceAction = 0; public void Dance() { guardState = GuardState.Dance; if (lastDanceAction == GuardAction_Dance1) { NextAction = GuardAction_Run; lastDanceAction = GuardAction_Dance2; } else { NextAction = GuardAction_Dance1; lastDanceAction = GuardAction_Dance1; } } #endregion protected sealed override void OnFixedUpdate() { } protected sealed override void OnLateUpdate() { } public sealed override void ReleaseLifeBar() { } public sealed override void ReleaseName() { } public sealed override void RequestLifeBar() { } public sealed override void RequestName() { } public sealed override void RequestShadow() { } public override void OnClick() { throw new System.NotImplementedException(); } public override void OnSelect() { throw new System.NotImplementedException(); } public override void OnUnSelect() { throw new System.NotImplementedException(); } public override bool CanBeSelected() { return false; } }