using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Cysharp.Threading.Tasks; using Framework; using Gameplay.Buff; using Gameplay.Character; using Gameplay.Effect; using Gameplay.Skill; using Gameplay.Unit; using Gameplay.Unit.Data; using Gameplay.Utils; using PhxhSDK; using Constants = Framework.Constants; namespace Gameplay.Summon { using cfg.SummonCfg; using Level; using LTGame; using UnityEngine; public class BaseSummon : GameUnit { public readonly DataSummon configData; public readonly SummonRuntimeData runtimeData; protected NStateMachine _fsm; public readonly GameUnit creator; private int _lastCellIndex; private Transform _bottomPanelTrans; public BaseSummon(DataSummon configData, uint id, GameUnit creator) : base(id, creator.commonData.troopId, EGameUnitType.Summon) { // TODO: 暂时不知道从哪里读 commonData.level = 1; this.creator = creator; this.configData = configData; runtimeData = new SummonRuntimeData(); runtimeData.remainExistTime = configData.ExistTime; commonData.canControl = false; statusData.canBeAttack = configData.CanBeAttack; commonData.standLevel = configData.StandCrossLevel; commonData.crossLevel = configData.MoveCrossLevel; _CopyPropFromCreator(); _OverridePropFromCreator(); } private void _CopyPropFromCreator() { creator.fightData.CopyTo(fightData); aliveData.maxHp = creator.aliveData.maxHp; aliveData.currentHp = creator.aliveData.maxHp; aliveData.currentShield = creator.aliveData.currentShield; aliveData.maxShield = creator.aliveData.maxShield; aliveData.currentMorale = creator.aliveData.currentMorale; aliveData.maxMorale = creator.aliveData.maxMorale; } private void _OverridePropFromCreator() { if (configData.Hp > -1) { aliveData.maxHp = configData.Hp; aliveData.currentHp = configData.Hp; } if (configData.Shiled > -1) { aliveData.maxShield = configData.Shiled; aliveData.currentShield = configData.Shiled; } } private void _InitFsm() { _OnInitFsm(); } protected virtual void _OnInitFsm() { _fsm = new NStateMachine(); _fsm.Add(new SummonStateWaitRemove(this)); } public async void Create() { var modelPath = PathEx.GetSummonGameModelPath(configData.ModelPath); GameUnitManager.instance.RecordLoadPath(modelPath); var loadObj = await AssetManager.Instance.LoadAssetAsync(modelPath); if (loadObj == null) { return; } if (Node == null || Node.GameObject == null) { // 创建出来就炸了 return; } var instObj = Object.Instantiate(loadObj, Node.GameObject.transform); instObj.transform.localPosition = Vector3.zero; instObj.transform.localRotation = Quaternion.identity; instObj.transform.localScale = Vector3.one; var isSelf = creator.commonData.troopId == ETroopsId.Self; var bottomPanelPath = isSelf ? Constants.SUMMON_BOTTOM_PATH_SELF : Constants.SUMMON_BOTTOM_PATH_ENEMY; var sampleObj = await AssetManager.Instance.LoadAssetAsync(bottomPanelPath); if (sampleObj == null) { DebugUtil.LogError("找不到召唤物底座:" + bottomPanelPath); return; } var bottomPanelObj = Object.Instantiate(sampleObj, EffectManager.instance.rootObj.transform); _bottomPanelTrans = bottomPanelObj.transform; _bottomPanelTrans.position = Node.GameObject.transform.position; Node.GameObject.SetLayerEx(Node.GameObject.layer); isReady = true; if (configData.IsShowHeadUI) { // 需要显示头顶UI EventManager.Instance.Send(EventManager.EventName.INFIGHT_SUMMON_CREATED, this); } } public void Init(int createCellIndex, float yaw) { _InitNode(createCellIndex, yaw); _OnInited(); _InitFsm(); BuffManager.instance.InitSummon(this); } private void _InitNode(int createCellIndex, float yaw) { var map = LevelManager.Instance.CurrentLevel.Map; var worldPos = map.TGSCellIndex2WorldPosition(createCellIndex); transData.pos = worldPos; transData.yaw = yaw; Node.GameObject.transform.SetPositionAndRotation(transData.pos, transData.rot); _lastCellIndex = createCellIndex; } protected virtual void _OnInited() { } protected override void _OnLogicUpdate(float dt) { base._OnLogicUpdate(dt); _UpdateExitTime(dt); _fsm.LogicUpdate(dt); _UpdateTrans(dt); _UpdateBottomObjShow(); } private void _UpdateBottomObjShow() { if (_bottomPanelTrans == null) return; var map = LevelManager.Instance.CurrentLevel.Map; if (map == null) return; var needShow = map.CheckIsShow(Map.InfoMask.ShowCells); if (_bottomPanelTrans.gameObject.activeSelf != needShow) { _bottomPanelTrans.gameObject.SetActive(needShow); } } private void _UpdateExitTime(float dt) { runtimeData.remainExistTime -= dt; } private void _UpdateTrans(float dt) { if (IsDispose()) return; if (transData.isTransChanged) { Node.GameObject.transform.SetPositionAndRotation(transData.pos, transData.rot); var newCellIndex = transData.cellIndex; if (newCellIndex != _lastCellIndex) { _lastCellIndex = newCellIndex; var pos = LevelManager.Instance.CurrentLevel.Map.TGSCellIndex2WorldPosition(_lastCellIndex); _bottomPanelTrans.position = pos; } } transData.Reset(); } protected float _ReatFloatParam(int index) { if (configData.FloatParams.Count <= index) { DebugUtil.LogError("技能参数不足: " + configData.RoleID + " " + index); return 0; } return configData.FloatParams[index]; } protected int _ReadIntParam(int index) { var floatVal = _ReatFloatParam(index); return Mathf.RoundToInt(floatVal); } protected override void OnDispose() { // 销毁底座 if (_bottomPanelTrans != null) { Object.Destroy(_bottomPanelTrans.gameObject); _bottomPanelTrans = null; } // 播放销毁特效 if (configData.DestroyEffectId > 0) { EffectManager.instance.PlayEffectById(configData.DestroyEffectId, Node.GameObject.transform.position, Node.GameObject.transform.rotation); } // 播放销毁音效 if (configData.DestroyAudioId > 0) { AudioManager.Instance.PlayAudio(configData.DestroyAudioId, Node.GameObject.transform.position).Forget(); } base.OnDispose(); } } }