using cfg.LevelCfg; using System.Collections.Generic; using Code.Scripts.Gameplay.Utils; using Cysharp.Threading.Tasks; using Framework; using Gameplay.AI; using Gameplay.Area; using Gameplay.Buff; using Gameplay.Character; using Gameplay.Effect; using Gameplay.Emoji; using Gameplay.Pause; using Gameplay.Pool; using Gameplay.Skill; using Gameplay.SubSystems; using Gameplay.Unit; using Gameplay.Vehicle; using PhxhSDK; using UnityEngine; using Constants = Framework.Constants; namespace Gameplay.Level { public partial class Level : IUpdatable, ILoadable { private int _id; private LevelData _levelData; private LevelInfo _currLevelInfo; private Map _map; private StateMachine _stateMachine = new StateMachine(); public bool isInBattle = false; private object _param; public int ID => _id; public Map Map => _map; public float LevelTime { set; get; } public bool IsPvPLevel => _id == TableManager.Instance.Tables.GlobalConfig.PVPLevelID; public Level(int leveId, object param = null) { _id = leveId; _param = param; Init(); } private Dictionary _configLevelDic = new Dictionary(); public Dictionary ConfigLevelDic => _configLevelDic; private void LoadConfigLevel() { _currLevelInfo = LevelManager.Instance.GetLevelInfoByID(_id); } private async UniTask LoadScene() { await GameSceneManager.Instance.LoadSceneAsync(_currLevelInfo.LevelScene); } private async UniTask UnLoadScene() { await GameSceneManager.Instance.UnLoadSceneAsync(_currLevelInfo.LevelScene); } private async UniTask LoadData() { _levelData = _currLevelInfo.LevelData; } private async UniTask LoadMap() { // if (_levelData != null) // { // if (_map != null) // { // MapUtils.RemoveCameraController(CameraManager.Instance.MainCamera); // MapUtils.UnLoadMap(_map); // } _map = await MapUtils.LoadMap(_currLevelInfo.MapData); //NLDSceneManager.Instance.SceneCamera.gameObject.SetActive(false); var sceneCamera = NLDSceneManager.Instance.SceneCamera; // Debug.LogError(sceneCamera.scene + " " + sceneCamera.name); CameraManager.Instance.SwitchMainCamera(sceneCamera); MapUtils.BindCameraController(NLDSceneManager.Instance.SceneCamera, _map); //MapUtils.BindCameraController(CameraManager.Instance.MainCamera, _map); //} } private async UniTask LoadNpc() { if (!IsPvPLevel) await LoadNPCFromLevelData(); else await LoadNPCFromPVPData(); } private async UniTask LoadNPCFromLevelData() { if (_levelData != null && _map != null) { for (var i = 0; i < _levelData.npcInfos.Count; i++) { var npcInfo = _levelData.npcInfos[i]; // TODO: LT:临时处理,后续需要根据配置来 var teamId = ETroopsId.Enemy1; var cellIndex = _map.BlockPosition2TGSCellIndex(npcInfo.position); var yaw = LevelUtils.SetCharaterToward(npcInfo.npcToward); var npcCharacter = await GameUnitManager.instance.PrepareNpc(npcInfo, teamId) as Character.Character; if (npcCharacter == null) { DebugUtil.LogError("创建npc失败"); continue; } npcCharacter.runtimeData.characterLevelData = new CharacterLevelData() { AttachAIName = npcInfo.attachAIType, AIName = npcInfo.aIType, BornPosition = npcInfo.position, NpcToward = npcInfo.npcToward, PatrolInfos = npcInfo.patrolInfos }; npcCharacter.transData.bornCellIndex = cellIndex; GameUnitManager.instance.MoveUnitToFight(npcCharacter.GetID(), cellIndex, yaw); } } } private async UniTask LoadNPCFromPVPData() { var pvpDefenderData = _param as PVPDefenderData; if (pvpDefenderData == null) { DebugUtil.LogError("pvp参数不合法!"); return; } for (var i = 0; i < pvpDefenderData.pvpRuntimeUnitInfos.Count; i++) { var pvpUnitData = pvpDefenderData.pvpRuntimeUnitInfos[i]; //var id = (uint)pvpUnitData.unitID; var position = _map.TGSCellIndex2BlockPosition(pvpUnitData.cellIndex); var teamId = ETroopsId.Enemy1; GameUnit unit = null; switch (pvpUnitData.type) { case Framework.Wrapper.Unit.UnitType.Charactor: var cInfo = new CharacterDataInfo(); cInfo.Refresh(pvpUnitData.characterInfo); unit = await GameUnitManager.instance.PrepareCharacter(cInfo, teamId); var character = (Character.Character)unit; character.runtimeData.characterLevelData = new CharacterLevelData() { AttachAIName = pvpUnitData.attachAIType, AIName = pvpUnitData.aiType, BornPosition = position, NpcToward = _levelData.pvpDefendToward, PatrolInfos = new(), }; break; case Framework.Wrapper.Unit.UnitType.Vehicle: //todo VehicleCultivateData第二个参数 var vInfo = new VehicleCultivateData(); vInfo.Refresh(pvpUnitData.vehicleInfo); unit = await GameUnitManager.instance.PrepareVehicle(vInfo, teamId); break; default: break; } if (unit == null) { DebugUtil.LogError("创建pvp unit失败"); continue; } var yaw = LevelUtils.SetCharaterToward(_levelData.pvpDefendToward); GameUnitManager.instance.MoveUnitToFight(unit.GetID(), pvpUnitData.cellIndex, yaw); } } // public void BindMap(Map map) // { // if (map != null) // { // _map = map; // } // // if (_map.MapData.name.Equals(_levelData.mapName)) // { // DebugUtil.LogError("{0}.{1} Error:map name not match", GetType(), // System.Reflection.MethodBase.GetCurrentMethod()?.Name); // } // } public void Update(float deltaTime) { if (!_isPause) { _stateMachine.Update(deltaTime * _speed); // GameUnitManager.instance.LogicUpdate(deltaTime * _speed); AIManager.Instance.Update(deltaTime * _speed); SelecterView.Instance.Update(deltaTime * _speed); } } /// /// 这里是 level system的初始化,不是 level 场景的初始化 /// public void Init() { AIManager.Instance.Init(); GameUnitManager.CreateInstance(); SkillManager.CreateInstance(); BuffManager.CreateInstance(); EmojiManager.CreateInstance(); } public void Release() { AreaManager.instance.Dispose(); EmojiManager.inst.Dispose(); SkillManager.instance.Dispose(); BuffManager.instance.Dispose(); _stateMachine?.ChangeState(null); AIManager.Instance.Release(); // 在这里释放所有单位 GameUnitManager.instance.Dispose(); if (PauseManager.instance != null) { PauseManager.instance.Dispose(); } EffectManager.instance.ClearPool(); ObjPoolManager.instance.Clear(); //GameUnitManager.instance.Dispose(); AssetManager.Instance.Unload(Constants.TIREMARK_UNIT_PATH); AssetManager.Instance.Unload(Constants.TIREMARK_MAT_PATH); AssetManager.Instance.Unload(Constants.CHARACTER_SELECT_GROUND_GFX); AssetManager.Instance.Unload(Constants.EMOJI_HEAD_MAT); AssetManager.Instance.Unload(Constants.SUMMON_BOTTOM_PATH_SELF); AssetManager.Instance.Unload(Constants.SUMMON_BOTTOM_PATH_ENEMY); AssetManager.Instance.Unload(Constants.SKILL_GORUND_HIGH_LIGHT); _UnLoadWeather(); } private void _UnLoadWeather() { var weatherType = (int)_currLevelInfo.WeatherType; var weatherConfig = TableManager.Instance.Tables.WeatherConfig.Get(weatherType); if (weatherConfig == null) { DebugUtil.LogError("天气配置错误:{0}", weatherType); return; } var cameraPrefab = weatherConfig.CameraPrefab; if (string.IsNullOrEmpty(cameraPrefab)) { return; } AssetManager.Instance.Unload(cameraPrefab); } public async UniTask Load() { LoadConfigLevel(); // GameUnitManager.instance.PrepareUnits(); UIManager.Instance.CloseAllNormalExcept(UINameConst.UI_Loading); await LoadScene(); await LoadData(); await LoadMap(); await _LoadWeather(); await _InitAfterLoadMap(); await _LoadOthers(); await LoadNpc(); _SetShadows(); RegisterAllEvent(); InitRules(); _stateMachine.ChangeState(new PrepareState(this)); SelecterView.Instance.Init(); } private async UniTask _LoadWeather() { var weatherType = (int)_currLevelInfo.WeatherType; var weatherConfig = TableManager.Instance.Tables.WeatherConfig.Get(weatherType); if (weatherConfig == null) { DebugUtil.LogError("天气配置错误:{0}", weatherType); return; } var cameraPrefab = weatherConfig.CameraPrefab; if (string.IsNullOrEmpty(cameraPrefab)) { return; } var loadObj = await AssetManager.Instance.LoadAssetAsync(cameraPrefab); if (loadObj == null) { DebugUtil.LogError("加载天气特效失败:{0}", cameraPrefab); return; } var cameraObj = CameraManager.Instance.MainCamera.gameObject; var weatherCamera = Object.Instantiate(loadObj, cameraObj.transform); weatherCamera.transform.localPosition = Vector3.zero; weatherCamera.transform.localRotation = Quaternion.identity; } private void _SetShadows() { var setDistance = _currLevelInfo.ShadowDistance; ShadowEx.SetShadowDistance(setDistance); } private async UniTask _LoadOthers() { AssetManager.Instance.PostPreload(Constants.TIREMARK_UNIT_PATH); AssetManager.Instance.PostPreload(Constants.TIREMARK_MAT_PATH); AssetManager.Instance.PostPreload(Constants.CHARACTER_SELECT_GROUND_GFX); AssetManager.Instance.PostPreload(Constants.EMOJI_HEAD_MAT); AssetManager.Instance.PostPreload(Constants.SUMMON_BOTTOM_PATH_SELF); AssetManager.Instance.PostPreload(Constants.SUMMON_BOTTOM_PATH_ENEMY); AssetManager.Instance.PostPreload(Constants.SKILL_GORUND_HIGH_LIGHT); await AssetManager.Instance.WaitAllPreloads(); } private async UniTask _InitAfterLoadMap() { // 加载后处理 await _LoadPostProcess(); AreaManager.CreateInstance(); // 表情相关 AssetManager.Instance.PostPreload(Constants.EMOJI_PREFAB_PATH); await AssetManager.Instance.WaitAllPreloads(); } private async UniTask _LoadPostProcess() { // 加载shader AssetManager.Instance.PostPreload(Constants.SHADER_OUTLINE_PATH1); AssetManager.Instance.PostPreload(Constants.SHADER_OUTLINE_PATH1_1); AssetManager.Instance.PostPreload(Constants.SHADER_OUTLINE_PATH2); AssetManager.Instance.PostPreload(Constants.SHADER_OUTLINE_PATH3); await AssetManager.Instance.WaitAllPreloads(); var loadObj = await AssetManager.Instance.LoadAssetAsync(Constants.OUTLINE_POSTPROCESS_PATH); if (loadObj != null) { Object.Instantiate(loadObj); } } public void BeginBattle() { _stateMachine.ChangeState(new BattleState(this)); } public bool IsPreparing() { return _stateMachine.GetCurrentState() is PrepareState; } public bool IsInBattle() { return isInBattle; } public bool IsEnd() { return _stateMachine.GetCurrentState() is EndState; } public async UniTask Unload() { //MapUtils.RemoveCameraController(CameraManager.Instance.MainCamera); CameraManager.Instance.RevertMainCamera(); MapUtils.UnLoadMap(_map); UnRegisterAllEvent(); ReleaseRules(); SelecterView.Instance.Release(); await UnLoadScene(); await UniTask.NextFrame(); } public LevelData GetLevelData() { return _levelData; } private const string DescKey = "LevelDesc{0}"; private const string NameKey = "LevelName{0}"; public string GetLevelName() { return StringManager.Instance.GetLocalizeTextByKey(string.Format(NameKey, _id)); } public string GetLevelDesc(LevelData levelData) { return StringManager.Instance.GetLocalizeTextByKey(string.Format(DescKey, _id)); } } }