using System; using System.Collections; using vnxbqy.UI; using UnityEngine; public class GA_Guard : GActorNpcNoFight { public enum GuardState { Idle, Track, Dance, PickUp, Inter, } #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 public bool IsStateActive { get; set; }//是否状态机开启 public bool guardPick { get; private set; } public float animatorSpeed { get; private set; } public bool stopDanceState { get; set; } public GuardState guardState { get; set; } public int targetPlayerId { get; private set; } public int itemID { get; set; } public int[] pickEffectIds { get; private set; } public bool IsHeroControl { get { return targetPlayerId == PlayerDatas.Instance.PlayerId; } } public bool IsPlayerDie { get; private set; } PlayerDeadModel deadModel { get { return ModelCenter.Instance.GetModel(); } } GuardModel model { get { return ModelCenter.Instance.GetModel(); } } DungeonModel dungeonModel { get { return ModelCenter.Instance.GetModel(); } } public GActorPlayerBase targetPlayer { get { if (targetPlayerId == PlayerDatas.Instance.PlayerId) { return PlayerDatas.Instance.hero; } else { return GAMgr.Instance.GetBySID((uint)targetPlayerId) as GActorPlayerBase; } } } public GuardPickupItem pickUpBehaviour { get; private set; } private SFXController m_SFXController = null; 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 (IsHeroControl) { StageLoad.Instance.onStageLoadFinish += OnStageLoadFinish; DTC0102_tagCDBPlayer.afterPlayerDataInitializeEvent += AfterPlayerDataInitializeEvent; DTCA112_tagMCDBPlayer.playerInitEvent += PlayerInitEvent; } IsPlayerDie = false; if (IsHeroControl) { pickUpBehaviour = Root.AddMissingComponent(); pickUpBehaviour.guard = this; } else { pickUpBehaviour = Root.GetComponent(); if (pickUpBehaviour != null) { UnityEngine.Object.DestroyImmediate(pickUpBehaviour); } } } public void InitBase() { var config = GuardConfig.Get(itemID); if (config != null) { pickEffectIds = config.effectIds; guardPick = config.autoPick == 1; } InitializeModelRes(); } protected sealed override void OnUnit() { deadModel.AllPlayerDieEvent -= AllPlayerDieEvent; deadModel.AllPlayerRebornEvent -= AllPlayerRebornEvent; DTC0429_tagObjResetPos.ResetPlayerPosEvent -= ResetPlayerPosEvent; DTC0102_tagCDBPlayer.afterPlayerDataInitializeEvent -= AfterPlayerDataInitializeEvent; DTCA112_tagMCDBPlayer.playerInitEvent -= PlayerInitEvent; if (IsHeroControl) { StageLoad.Instance.onStageLoadFinish -= OnStageLoadFinish; ReleasePickUpBehaviour(); } if (m_SFXController != null) { SFXPlayUtility.Instance.Release(m_SFXController); } if (m_Animator != null) { m_Animator.speed = animatorSpeed; NextAction = GuardAction_Idle; } guardState = GuardState.Idle; IsStateActive = false; pickUpBehaviour = null; base.OnUnit(); } private void AfterPlayerDataInitializeEvent() { SnxxzGame.Instance.StartCoroutine(Co_RecheckPlayLifeState()); } public void PlayerInitEvent() { CheckResetGuardState(); } IEnumerator Co_RecheckPlayLifeState() { yield return null; CheckResetGuardState(); } void CheckResetGuardState() { if (guardState == GuardState.Inter) { var hero = PlayerDatas.Instance.hero; if (hero != null) { if (hero.ActorInfo != null && !hero.ActorInfo.serverDie) { IsPlayerDie = false; IsStateActive = true; if (m_Animator) { m_Animator.enabled = true; } SetPosition(hero.Pos.x / 2, hero.Pos.y / 2); } } } } private void ReleasePickUpBehaviour() { if (pickUpBehaviour != null) { pickUpBehaviour.ReleaseSfx(); } } private void OnStageLoadFinish() { if (m_Model == null) { return; } SnxxzGame.Instance.StartCoroutine(Co_StagePrepare()); } IEnumerator Co_StagePrepare() { yield return null; if (Root != null && targetPlayer != null) { var targetPosition = targetPlayer.Root.position; if (MathUtility.CalDistance(Root.position, targetPosition) > model.resetDistance * model.resetDistance) { SetPosition(targetPosition.x, targetPosition.z); } if (m_SFXController == null || !m_SFXController.gameObject.activeSelf) { m_SFXController = SFXPlayUtility.Instance.PlayBattleEffect(pickEffectIds[0], this, NpcConfig != null ? NpcConfig.ModeProportion : 1); if (m_SFXController != null) { var mountPoint = Root.GetChildTransformDeeply(GAStaticDefine.MountPointBoneName); m_SFXController.duration = 0; m_SFXController.transform.SetParent(mountPoint); m_SFXController.transform.localPosition = Vector3.zero; m_SFXController.transform.localEulerAngles = 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; } SetPosition(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) > model.resetDistance * model.resetDistance) { SetPosition(vNetData.PosX / 2, vNetData.PosY / 2); } } } protected override sealed void OnPrefabLoadFinished(bool result, UnityEngine.Object prefab) { if (!result || prefab == null) { return; } if (m_Model) { if (NpcConfig != null) { GameObject _toDestroy = InstanceResourcesLoader.LoadNpc(NpcConfig.NPCID); if (_toDestroy) { GameObjectPoolManager.Instance.ReleaseGameObject(_toDestroy, m_Model); } } else { UnityEngine.Object.Destroy(m_Model); } m_Model = null; m_Animator = null; } GAMgr.Instance.RemoveNeedDestroyPrefab(prefab as GameObject); m_Model = GameObjectPoolManager.Instance.RequestGameObject(prefab as GameObject); var _config = GuardConfig.Get(itemID); NpcConfig = NPCConfig.Get(_config.npcId); if (m_Model) { m_Animator = m_Model.GetComponent(); if (m_Animator) { RuntimeAnimatorController _controller = null; if (m_LoadDefaultRes) { _controller = AnimatorControllerLoader.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.localScale = Vector3.one; m_Model.transform.localRotation = Quaternion.identity; RequestName(); OnMainModelLoaded(); } } protected override void OnMainModelLoaded() { m_Model.SetLayer(LayerUtility.Monster, true); var mountPoint = Root.GetChildTransformDeeply(GAStaticDefine.MountPointBoneName); m_SFXController = SFXPlayUtility.Instance.PlayBattleEffect(pickEffectIds[0], this, NpcConfig != null ? NpcConfig.ModeProportion : 1); if (m_SFXController != null) { m_SFXController.duration = 0; m_SFXController.transform.SetParent(mountPoint); m_SFXController.transform.localPosition = Vector3.zero; m_SFXController.transform.localEulerAngles = Vector3.zero; } m_Animator.SetInteger(GAStaticDefine.Param_ActorInstID, (int)ClientInstID); m_Animator.enabled = true; animatorSpeed = m_Animator.speed; Idle(); if (IsHeroControl) { GameObjectPoolManager.Instance.AddDontDestroyGoInstID(m_Model.GetInstanceID()); } } private void InitializeModelRes() { IsStateActive = true; if (targetPlayer != null) { var bornpos = targetPlayer.Root.position + targetPlayer.Root.right * 0.6f - targetPlayer.Forward * 0.3f; bornpos.y = targetPlayer.Root.position.y + model.height; Pos = bornpos; } var _config = GuardConfig.Get(itemID); InstanceResourcesLoader.AsyncLoadNpc(_config.npcId, OnPrefabLoadFinished); } private void SetPosition(float x, float z) { if (targetPlayer == null) { return; } var pos = new Vector3(x, 0, z) + targetPlayer.Root.right.normalized * 0.6f - targetPlayer.Forward * 0.3f; pos.y = targetPlayer.Root.position.y + model.height; 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 (IsPlayerDied()) { return; } CheckDistance(); if (IsHeroControl && guardPick) { if (CheckPickupItem()) { return; } } CheckTrack(); } private void CheckDistance() { var _height = targetPlayer.Root.position.y + model.height; var targetPosition = targetPlayer.Root.position; if (MathUtility.CalDistance(Root.position, targetPosition) > model.resetDistance * model.resetDistance) { SetPosition(targetPosition.x, targetPosition.z); } else if (Mathf.Abs(Root.position.y - _height) > 2) { SetPosition(targetPosition.x, targetPosition.z); } } public void Disappear() { IsStateActive = false; ReleasePickUpBehaviour(); if (m_Model) { Root.position = Constants.Special_Hide_Position; } if (m_Animator) { m_Animator.enabled = false; m_Animator.speed = animatorSpeed; } } public override void Idle() { NextAction = GuardAction_Idle; guardState = GuardState.Idle; } private bool CheckTrack() { if (MathUtility.CalDistance(Root.position, targetPlayer.Root.position) > model.traceRange * model.traceRange && guardState != GuardState.Track) { stopDanceState = true; NextAction = GuardAction_Run; guardState = GuardState.Track; return true; } return false; } private bool IsPlayerDied() { if (IsPlayerDie) { if (guardState != GuardState.Track && guardState != GuardState.Inter) { stopDanceState = true; guardState = GuardState.Inter; NextAction = GuardAction_Run; } return true; } return false; } public bool CheckPickupItem() { if (Root == null) { return false; } if (DropItemManager.CheckCanGuardPickUp(Root.position)) { var dataMapId = dungeonModel.GetDataMapIdByMapId(PlayerDatas.Instance.baseData.MapID); if (dataMapId != 0) { var dungeonConfig = DungeonOpenTimeConfig.Get(dataMapId); if (dungeonConfig != null) { if (dungeonConfig.GuardPick == 0) { return false; } } } if (guardState != GuardState.PickUp) { stopDanceState = true; guardState = GuardState.PickUp; if (NextAction != GuardAction_Run) { NextAction = GuardAction_Run; } 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; } }