using System; using AlicizaX.ObjectPool; using Cysharp.Threading.Tasks; using UnityEngine; namespace AlicizaX { /// /// 基础组件。 /// [DisallowMultipleComponent] [UnityEngine.Scripting.Preserve] public sealed class RootModule : MonoBehaviour { private static RootModule _instance = null; public static RootModule Instance { get { if (_instance == null) { _instance = FindObjectOfType(); } return _instance; } } private const int DEFAULT_DPI = 96; private float _gameSpeedBeforePause = 1f; [SerializeField] private int frameRate = 120; [SerializeField] private float gameSpeed = 1f; [SerializeField] private bool runInBackground = true; [SerializeField] private bool neverSleep = true; /// /// 获取或设置游戏帧率。 /// public int FrameRate { get => frameRate; set => Application.targetFrameRate = frameRate = value; } /// /// 获取或设置游戏速度。 /// public float GameSpeed { get => gameSpeed; set => Time.timeScale = gameSpeed = value >= 0f ? value : 0f; } /// /// 获取游戏是否暂停。 /// public bool IsGamePaused => gameSpeed <= 0f; /// /// 获取是否正常游戏速度。 /// public bool IsNormalGameSpeed => Math.Abs(gameSpeed - 1f) < 0.01f; /// /// 获取或设置是否允许后台运行。 /// public bool RunInBackground { get => runInBackground; set => Application.runInBackground = runInBackground = value; } /// /// 获取或设置是否禁止休眠。 /// public bool NeverSleep { get => neverSleep; set { neverSleep = value; Screen.sleepTimeout = value ? SleepTimeout.NeverSleep : SleepTimeout.SystemSetting; } } /// /// 暂停游戏。 /// public void PauseGame() { if (IsGamePaused) { return; } _gameSpeedBeforePause = GameSpeed; GameSpeed = 0f; } /// /// 恢复游戏。 /// public void ResumeGame() { if (!IsGamePaused) { return; } GameSpeed = _gameSpeedBeforePause; } /// /// 重置为正常游戏速度。 /// public void ResetNormalGameSpeed() { if (IsNormalGameSpeed) { return; } GameSpeed = 1f; } /// /// 游戏框架组件初始化。 /// private void Awake() { _instance = this; DontDestroyOnLoad(this); Utility.Unity.MakeEntity(transform); Log.Init(); Log.Info("Game Version: {0}, Unity Version: {1}", AppVersion.GameVersion, Application.unityVersion); Utility.Converter.ScreenDpi = Screen.dpi; if (Utility.Converter.ScreenDpi <= 0) { Utility.Converter.ScreenDpi = DEFAULT_DPI; } Application.targetFrameRate = frameRate; Time.timeScale = gameSpeed; Application.runInBackground = runInBackground; Screen.sleepTimeout = neverSleep ? SleepTimeout.NeverSleep : SleepTimeout.SystemSetting; Application.lowMemory += OnLowMemory; } private void OnApplicationQuit() { Application.lowMemory -= OnLowMemory; StopAllCoroutines(); Shutdown(); } internal void Shutdown() { Destroy(gameObject); Utility.Unity.Shutdown(); MemoryPool.ClearAll(); Utility.Marshal.FreeCachedHGlobal(); } private void Update() { ModuleSystem.UpdateExecuteList(Time.deltaTime, Time.unscaledDeltaTime); } private void LateUpdate() { ModuleSystem.UpdateLateExecuteList(); } private void FixedUpdate() { ModuleSystem.UpdateFixedExecuteList(); } private void OnDrawGizmos() { ModuleSystem.UpdateGizmosExecuteList(); } private void OnGUI() { ModuleSystem.UpdateGUIExecuteList(); } private async void OnDestroy() { await UniTask.Yield(); ModuleSystem.Dispose(); } private void OnLowMemory() { Log.Warning("Low memory reported..."); IObjectPoolModule objectPoolModule = ModuleSystem.GetModule(); if (objectPoolModule != null) { objectPoolModule.ReleaseAllUnused(); } } } }