using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using AibisDream.FixSystem;
using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.Utility;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using Yarn.Unity;
namespace AibisDream
{
///
/// 优化版本的GameManager,解决性能问题
///
public class GameManagerOptimized : Singleton, IGameManager
{
#region 运行模式相关
private TalkSceneSO[] _totalSceneSos;
private bool _isSceneSosLoaded = false;
public RunMode runMode;
[Header("生产环境数据(一般不动)")] public TalkSceneSO firstTalkSo;
[Header("单场景测试")] public TalkSceneSO testTalkSo;
[Header("存档测试")] public string saveFileName;
#endregion
private BindProperty _currentTalkSceneSo;
private readonly GameLoopData _data = new();
// 缓存组件引用,避免重复查找
private UIManager _uiManager;
private SceneLoader _sceneLoader;
private DialogController _dialogController;
private AudioManager _audioManager;
private ScreenEffectManager _screenEffectManager;
private DialogCanvasManager _dialogCanvasManager;
private CameraKit _cameraKit;
private StorageSystem _storageSystem;
// 性能监控
private PerformanceProfiler _performanceProfiler;
private PerformanceOptimizer _performanceOptimizer;
private void Awake()
{
// 预缓存所有需要的组件引用
CacheComponentReferences();
}
private void Start()
{
// 管理游戏开始时各部分的初始化
SettingLoader.Init();
// 数据类注册
_storageSystem.RegisterData(_data);
// 场景So事件注册
_currentTalkSceneSo = new BindProperty();
_currentTalkSceneSo.Register(item => _data.curSceneSoName = item.name);
// 事件广播
EnumEventSystem.Global.Send(GameLoopEnum.AppStart);
// 异步加载SO,避免阻塞主线程
StartCoroutine(LoadSceneSOsAsync());
#if UNITY_EDITOR
if (runMode == RunMode.SingleScene)
{
StartWithLevel(testTalkSo);
}
else if (runMode == RunMode.SaveFile)
{
StartWithSaveFile($"{ConstRef.TestSaveFilePath}/{saveFileName}");
}
else
{
StartCoroutine(LoadInitialSceneAsync());
}
#else
_sceneLoader.LoadScene("ClinicOut");
runMode = RunMode.Product;
#endif
}
///
/// 缓存组件引用,避免重复的FindObjectOfType调用
///
private void CacheComponentReferences()
{
_uiManager = UIManager.Instance;
_sceneLoader = SceneLoader.Instance;
_dialogController = DialogController.Instance;
_audioManager = AudioManager.Instance;
_screenEffectManager = ScreenEffectManager.Instance;
_dialogCanvasManager = DialogCanvasManager.Instance;
_cameraKit = CameraKit.Instance;
_storageSystem = StorageSystem.Instance;
// 性能监控组件
_performanceProfiler = FindObjectOfType();
_performanceOptimizer = FindObjectOfType();
}
///
/// 异步加载场景SO,避免阻塞主线程
///
private IEnumerator LoadSceneSOsAsync()
{
var handle = Addressables.LoadAssetsAsync("SceneSO", null);
while (!handle.IsDone)
{
yield return null;
}
if (handle.Status == AsyncOperationStatus.Succeeded)
{
_totalSceneSos = handle.Result.ToArray();
_isSceneSosLoaded = true;
Debug.Log($"成功加载 {_totalSceneSos.Length} 个场景SO");
}
else
{
Debug.LogError("加载场景SO失败");
}
Addressables.Release(handle);
}
///
/// 异步加载初始场景
///
private IEnumerator LoadInitialSceneAsync()
{
yield return _uiManager.GetPanel().FadeInAsync(0);
yield return _sceneLoader.LoadSceneAsync("ClinicOut");
yield return _uiManager.GetPanel().FadeOutAsync();
}
#region 游戏循环
public void StartNewGame()
{
// 游戏开始
EnumEventSystem.Global.Send(GameLoopEnum.GameStart);
// 重置屏幕效果
_screenEffectManager?.ResetSaturation();
// 序列
_currentTalkSceneSo.Value = firstTalkSo;
StartCoroutine(LoadFirstScene());
}
public void StartWithLevel(TalkSceneSO sceneSo)
{
// 游戏开始
EnumEventSystem.Global.Send(GameLoopEnum.GameStart);
// 重置屏幕效果
_screenEffectManager?.ResetSaturation();
_currentTalkSceneSo.Value = sceneSo;
StartCoroutine(LoadFirstScene());
}
public void StartWithSaveFile(string fileName)
{
// 游戏开始
EnumEventSystem.Global.Send(GameLoopEnum.GameStart);
_storageSystem.Load(fileName);
}
private IEnumerator LoadFirstScene()
{
yield return _uiManager.GetPanel().FadeInAsync(0.5f);
yield return _sceneLoader.LoadSceneAsync(_currentTalkSceneSo.Value.firstSceneName);
_dialogController.StartDialog(_currentTalkSceneSo.Value.yarnProject);
}
public void PauseGame()
{
// 系统暂停
Time.timeScale = 0;
// 交互继续
EnumEventSystem.Global.Send(GameLoopEnum.PauseGame);
// 音频全部暂停
_audioManager.PauseAll();
// 关闭Dialog
_dialogCanvasManager.CloseCanvas();
}
public void ContinueGame()
{
// 系统继续
Time.timeScale = 1;
// 交互继续
EnumEventSystem.Global.Send(GameLoopEnum.UnPauseGame);
// 音频继续
_audioManager.UnPauseAll();
// 打开Dialog
_dialogCanvasManager.OpenCanvas();
}
public void QuitGame()
{
// 系统继续
Time.timeScale = 1;
// 重置屏幕效果
_screenEffectManager?.ResetSaturation();
// 卸载当前场景
StartCoroutine(RestartCoroutine());
}
public void QuitApp()
{
// 清理资源
CleanupResources();
Application.Quit();
}
///
/// 清理资源,避免内存泄漏
///
private void CleanupResources()
{
// 记录性能数据
_performanceProfiler?.LogPerformanceData();
// 清理对象池
var objectPool = FindObjectOfType();
objectPool?.ClearAllPools();
// 清理其他资源
Resources.UnloadUnusedAssets();
System.GC.Collect();
}
private IEnumerator RestartCoroutine()
{
_uiManager.GetPanel().FadeInSync(0.1f);
// 清理所有系统注册
if (FixSystemCenter.SystemDic != null)
{
FixSystemCenter.SystemDic.Clear();
}
// 执行场景切换等功能
_cameraKit.ResetCamera();
yield return _sceneLoader.LoadSceneAsync("ClinicOut");
_dialogController.StopDialog();
EnumEventSystem.Global.Send(GameLoopEnum.GameQuit);
// 音频继续
_audioManager.UnPauseAll();
// 打开Dialog
_dialogCanvasManager.OpenCanvas();
yield return _uiManager.GetPanel().FadeOutAsync();
}
#endregion
#region 分辨率与屏幕模式
public void SetScreenMode(string windowMode)
{
switch (windowMode)
{
case "FullScreen":
Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, FullScreenMode.FullScreenWindow);
break;
case "Windowed":
Screen.SetResolution(1920, 1080, FullScreenMode.Windowed);
break;
case "MaximizedWindow":
Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, FullScreenMode.MaximizedWindow);
break;
default:
Debug.Log($"{windowMode} err");
break;
}
}
#endregion
public IEnumerator NextSceneSo()
{
if (_currentTalkSceneSo.Value && _currentTalkSceneSo.Value.nextScene)
{
_currentTalkSceneSo.Value = _currentTalkSceneSo.Value.nextScene;
yield return _uiManager.GetPanel().FadeInAsync();
yield return _sceneLoader.LoadSceneAsync(_currentTalkSceneSo.Value.firstSceneName);
_dialogController.StartDialog(_currentTalkSceneSo.Value.yarnProject);
}
else
{
yield return null;
Debug.Log("没有下个场景了");
}
}
public void SetSceneSoByName(string soName)
{
if (!_isSceneSosLoaded)
{
Debug.LogWarning("场景SO尚未加载完成,无法设置场景");
return;
}
_currentTalkSceneSo.Value = Array.Find(_totalSceneSos, so => so.name == soName);
}
public void StartDialog()
{
_dialogController.LoadDialog(_currentTalkSceneSo.Value.yarnProject);
}
public string GetSceneSoName()
{
return _currentTalkSceneSo.Value.name;
}
///
/// 获取性能报告
///
public void GetPerformanceReport()
{
_performanceOptimizer?.CreatePerformanceReport();
}
}
}