using System; using UnityEngine; namespace XGame.Framework.Quality { public class QualityModule : IQualityModule, IDisposable { private XQualityLevel _recommendQuality; public XQualityLevel RecommendQuality { get { return _recommendQuality; } } private XQualityLevel _curQuality; public XQualityLevel CurQuality { get { return _curQuality; } set { if (value != _curQuality) ChangeQualityLevel(value); } } public Action OnQualityLevelChanged { get; set; } private Vector2Int _originalScreenSize; private const string SaveCurQualityKey = "CurQuality"; //private static IQualityModule _instance; //public static IQualityModule Instance //{ // get // { // if (_instance == null) _instance = new QualityModule(); // return _instance; // } //} public QualityModule() { _originalScreenSize = new Vector2Int(Screen.width, Screen.height); _curQuality = (XQualityLevel)PlayerPrefs.GetInt(SaveCurQualityKey, (int)XQualityLevel.UnKnow); CalcRecommendQuality(); InnerReset(); if (MacroDefine.IsEditor) Application.targetFrameRate = 60; else { Application.targetFrameRate = _curQuality == XQualityLevel.UltraHD ? 60 : 30; } Log.Info($"设备推荐的游戏品质:{_recommendQuality},用户设置的游戏品质:{_curQuality}"); } float IQualityModule.GetScreenScale() { return Screen.width * 1f / _originalScreenSize.x; } private float RecommendScreenScale(XQualityLevel level) { var scale = 1f; if (MacroDefine.IsAndroid) { switch (level) { case XQualityLevel.High: scale = 0.8f; break; case XQualityLevel.Medium: scale = 0.7f; break; case XQualityLevel.Low: scale = 0.7f; break; } } else if (MacroDefine.IsiOS) { switch (level) { case XQualityLevel.High: case XQualityLevel.Medium: scale = 0.8f; break; case XQualityLevel.Low: scale = 0.7f; break; } } return scale; } /// /// 判断是否模拟器函数 /// 通常Android才有模拟器 /// 模拟器可以模拟很多传感器信息 /// 此处选用光传感器判断 /// 实测雷电模拟器,夜神模拟器,网易mumu,腾讯手游助手都成功判断为模拟器 /// /// 是否模拟器 private static bool IsSimulator() { #if UNITY_ANDROID try { AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = unityPlayerClass.GetStatic("currentActivity"); AndroidJavaObject sensorManager = currentActivity.Call("getSystemService", "sensor"); AndroidJavaObject sensor = sensorManager.Call("getDefaultSensor", 5); //光传感器 return sensor == null; } catch (Exception e) { return false; } #endif return false; } private void CalcRecommendQuality() { //显存 int graphicsMemorySize = SystemInfo.graphicsMemorySize; //内存 int systemMemorySize = SystemInfo.systemMemorySize; //cpu核心数 int cpuCount = SystemInfo.processorCount; //cpu频率 int cpuFrequency = SystemInfo.processorFrequency; if (MacroDefine.IsEditor) { _recommendQuality = XQualityLevel.UltraHD; } else if (MacroDefine.IsAndroid) { //模拟器 if (IsSimulator()) { _recommendQuality = XQualityLevel.High; } //分辨率低于1344,4核心以下,主频低于1.5GHz,内存低于2GB,一律视为低端机 else if (Math.Max(_originalScreenSize.x, _originalScreenSize.y) < 1344 || cpuCount < 4 || cpuFrequency < 1500 || systemMemorySize <= 2048) { _recommendQuality = XQualityLevel.Low; } // 6核,内存4G,显存达到2G 高配 else if (cpuCount >= 6 && systemMemorySize > 3072 && graphicsMemorySize >= 2048) { _recommendQuality = XQualityLevel.High; } else { _recommendQuality = XQualityLevel.Medium; } } else if (MacroDefine.IsiOS) { //iphone 8s以上 if (SystemInfo.systemMemorySize > 2048) { _recommendQuality = XQualityLevel.High; } else { _recommendQuality = XQualityLevel.Medium; } } else { _recommendQuality = XQualityLevel.High; } if (_curQuality == XQualityLevel.UnKnow) ChangeQualityLevel(_recommendQuality); } private void ChangeQualityLevel(XQualityLevel ql) { // 保存 _curQuality = ql; PlayerPrefs.SetInt(SaveCurQualityKey, (int)_curQuality); // 内部逻辑设置 InnerReset(); // 外部逻辑设置 OnQualityLevelChanged?.Invoke(ql); Log.Info($"游戏品质等级切换到:{_curQuality}"); } private void InnerReset() { // 引擎设置 QualitySettings.SetQualityLevel((int)_curQuality); // 分辨率设置 ResetResolution(); // ShaderLod设置 Shader.globalMaximumLOD = _curQuality.ShaderLodLevel(); } // 分辨率设置 private void ResetResolution() { if (MacroDefine.IsEditor) return; if (MacroDefine.IsAndroid || MacroDefine.IsiOS) { //var refSize = new Vector2Int(1920, 1080); var refLength = 1080; var scale = RecommendScreenScale(_curQuality); if (Screen.orientation == ScreenOrientation.Portrait || Screen.orientation == ScreenOrientation.PortraitUpsideDown) { //竖屏 var width = (int)(refLength * scale); if (width >= _originalScreenSize.x) { width = _originalScreenSize.x; } if (width != Screen.width) { var height = (int)(width * _originalScreenSize.y * 1f / _originalScreenSize.x); Screen.SetResolution(width, height, Screen.fullScreen); } } else { //横屏 var height = (int)(refLength * scale); if (height >= _originalScreenSize.y) { height = _originalScreenSize.y; } if (height != Screen.height) { var width = (int)(height * _originalScreenSize.x * 1f / _originalScreenSize.y); Screen.SetResolution(width, height, Screen.fullScreen); } } } } void IDisposable.Dispose() { if (OnQualityLevelChanged != null) { OnQualityLevelChanged = null; } } } }