[펌] GameQualitySettings
Unity3D/Script / 2024. 1. 19. 15:28
// jave.lin 2022.03.17
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
// jave.lin : 输出系统的信息工具类
public class DumpSystemInfoUtil
{
// jave.lin : 通过反射得方式获取不了
public static string DumpSystemInfoByReflection()
{
var type = typeof(SystemInfo);
// jave.lin : 下面发现反射不成功
var fields = type.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
var fieldsToStrList = new List<string>();
foreach (var field in fields)
{
// 过滤 过期得 API
var obsoAttris = field.GetCustomAttributes(typeof(ObsoleteAttribute), true);
if (obsoAttris != null && obsoAttris.Length > 0) continue;
fieldsToStrList.Add(field.Name + ":" + field.GetValue(null).ToString());
}
return string.Join("\n", fieldsToStrList.ToArray());
}
// jave.lin : 所以只能通过一个个得去输出
public static string DumpSystemInfoByManualyPrint()
{
var list = new List<string>(
new string[]{
"SystemInfo:\n",
"\tbatteryLevel:" + SystemInfo.batteryLevel,
"\tbatteryStatus:" + SystemInfo.batteryStatus,
"\toperatingSystem:" + SystemInfo.operatingSystem,
"\toperatingSystemFamily:" + SystemInfo.operatingSystemFamily,
"\tprocessorType:" + SystemInfo.processorType,
"\tprocessorFrequency:" + SystemInfo.processorFrequency,
"\tprocessorCount:" + SystemInfo.processorCount,
"\tsystemMemorySize:" + SystemInfo.systemMemorySize,
"\tdeviceUniqueIdentifier:" + SystemInfo.deviceUniqueIdentifier,
"\tdeviceName:" + SystemInfo.deviceName,
"\tdeviceModel:" + SystemInfo.deviceModel,
"\tsupportsAccelerometer:" + SystemInfo.supportsAccelerometer,
"\tsupportsGyroscope:" + SystemInfo.supportsGyroscope,
"\tsupportsLocationService:" + SystemInfo.supportsLocationService,
"\tsupportsVibration:" + SystemInfo.supportsVibration,
"\tsupportsAudio:" + SystemInfo.supportsAudio,
"\tdeviceType:" + SystemInfo.deviceType,
"\tgraphicsMemorySize:" + SystemInfo.graphicsMemorySize,
"\tgraphicsDeviceName:" + SystemInfo.graphicsDeviceName,
"\tgraphicsDeviceVendor:" + SystemInfo.graphicsDeviceVendor,
"\tgraphicsDeviceID:" + SystemInfo.graphicsDeviceID,
"\tgraphicsDeviceVendorID:" + SystemInfo.graphicsDeviceVendorID,
"\tgraphicsDeviceType:" + SystemInfo.graphicsDeviceType,
"\tgraphicsUVStartsAtTop:" + SystemInfo.graphicsUVStartsAtTop,
"\tgraphicsDeviceVersion:" + SystemInfo.graphicsDeviceVersion,
"\tgraphicsShaderLevel:" + SystemInfo.graphicsShaderLevel,
"\tgraphicsMultiThreaded:" + SystemInfo.graphicsMultiThreaded,
"\tsupportsShadows:" + SystemInfo.supportsShadows,
"\tsupportsRawShadowDepthSampling:" + SystemInfo.supportsRawShadowDepthSampling,
"\tsupportsMotionVectors:" + SystemInfo.supportsMotionVectors,
"\tsupports3DTextures:" + SystemInfo.supports3DTextures,
"\tsupports2DArrayTextures:" + SystemInfo.supports2DArrayTextures,
"\tsupports3DRenderTextures:" + SystemInfo.supports3DRenderTextures,
"\tsupportsCubemapArrayTextures:" + SystemInfo.supportsCubemapArrayTextures,
"\tcopyTextureSupport:" + SystemInfo.copyTextureSupport,
"\tsupportsComputeShaders:" + SystemInfo.supportsComputeShaders,
"\tsupportsInstancing:" + SystemInfo.supportsInstancing,
"\tsupportsHardwareQuadTopology:" + SystemInfo.supportsHardwareQuadTopology,
"\tsupports32bitsIndexBuffer:" + SystemInfo.supports32bitsIndexBuffer,
"\tsupportsSparseTextures:" + SystemInfo.supportsSparseTextures,
"\tsupportedRenderTargetCount:" + SystemInfo.supportedRenderTargetCount,
"\tsupportsMultisampledTextures:" + SystemInfo.supportsMultisampledTextures,
"\tsupportsMultisampleAutoResolve:" + SystemInfo.supportsMultisampleAutoResolve,
"\tsupportsTextureWrapMirrorOnce:" + SystemInfo.supportsTextureWrapMirrorOnce,
"\tusesReversedZBuffer:" + SystemInfo.usesReversedZBuffer,
"\tnpotSupport:" + SystemInfo.npotSupport,
"\tmaxTextureSize:" + SystemInfo.maxTextureSize,
"\tmaxCubemapSize:" + SystemInfo.maxCubemapSize,
"\tsupportsAsyncCompute:" + SystemInfo.supportsAsyncCompute,
"\tsupportsAsyncGPUReadback:" + SystemInfo.supportsAsyncGPUReadback,
"\tsupportsMipStreaming:" + SystemInfo.supportsMipStreaming,
});
return string.Join("\n", list.ToArray());
}
}
// jave.lin : 设备定档级别枚举
public enum eDeviceLevel
{
Unknow = -1,
VeryLow = 0,
Low,
Middle,
High,
}
// jave.lin : 画质级别
public enum eQualityLevel
{
Low = 1,
Middle = 2,
High = 3,
Ultra = 4,
}
// jave.lin : shader lod
public enum eShaderLOD
{
//High = 800,
//Middle = 400,
//Low = 200,
//VeryLow = 100,
//UnLimit = -1,
// jave.lin : 太低的值对 built-in shader 的影响太大
High = 800,
Middle = 600,
Low = 400,
VeryLow = 200,
UnLimit = -1,
}
// jave.lin : 游戏的质量设置类
public class GameQualitySettings
{
private const string QS_POWER_SAVE_MODE_KEY = "graphics_setting.power_save_mode";
private const string QS_QUALITY_LEVEL_KEY = "graphics_setting.quality_level";
// 当 品质有调整事出发的事件函数
public static Action<eQualityLevel> onLevelChanged;
// 源来的 AA 和 阴影设置
private static int srcAntiAliasing;
private static ShadowQuality srcShadows;
// 当前 品质等级
private static eQualityLevel curLevel;
// 获取 设备定档的质量级别
public static eQualityLevel DeviceAdapterLevel
{
get; private set;
}
// 获取 或 设置 公开给外部的画质设置的属性
public static eQualityLevel GraphicsLevel
{
get { return curLevel; }
set
{
if (curLevel != value)
{
curLevel = value;
_SetCurLevel(value);
PlayerPrefs.SetInt(QS_QUALITY_LEVEL_KEY, (int)value);
if (null != onLevelChanged)
{
onLevelChanged.Invoke(value);
}
}
}
}
// 获取 或 设置 省电模式, true: 30FPS, false: 60FPS
public static bool PowerSaveMode
{
get
{
return Application.targetFrameRate < 40;
}
set
{
var src_v = PlayerPrefs.GetInt(QS_POWER_SAVE_MODE_KEY, -1);
var tar_v = value ? 1 : 0;
if (src_v != tar_v)
{
PlayerPrefs.SetInt(QS_POWER_SAVE_MODE_KEY, tar_v);
}
Application.targetFrameRate = value ? 30 : 60;
}
}
// 静态构造函数
static GameQualitySettings()
{
// 备份 原始 AA 和 阴影
srcAntiAliasing = QualitySettings.antiAliasing;
srcShadows = QualitySettings.shadows;
// 初始化 品质 和 省电模式
_SetDefaultPowerSaveMode();
_SetDefaultLevel();
}
// 设置默认的品质等级
private static void _SetDefaultLevel()
{
// 先 分析 并 设置 设备默认品质等级
DeviceAdapterLevel = _AnalysicDeviceLevel();
var src_v = PlayerPrefs.GetInt(QS_QUALITY_LEVEL_KEY, -1);
// 如果品质等级没有设置过
if (src_v == -1)
{
// 那么使用 设备默认品质
PlayerPrefs.SetInt(QS_QUALITY_LEVEL_KEY, (int)DeviceAdapterLevel);
curLevel = GraphicsLevel;
}
// 如果品质等级有设置过
else
{
curLevel = (eQualityLevel)src_v;
}
}
// 设置默认的省电模式
private static void _SetDefaultPowerSaveMode()
{
var src_v = PlayerPrefs.GetInt(QS_POWER_SAVE_MODE_KEY, 0);
if (src_v == 0)
{
PowerSaveMode = true;
PlayerPrefs.SetInt(QS_POWER_SAVE_MODE_KEY, 1);
}
else
{
PowerSaveMode = src_v == 1;
}
}
// 分析设备所属默认的品质等级
private static eQualityLevel _AnalysicDeviceLevel()
{
if (SystemInfo.processorFrequency >= 2500 &&
SystemInfo.processorCount >= 8 &&
SystemInfo.systemMemorySize >= (6 * 1024) &&
SystemInfo.graphicsMemorySize >= (2 * 1024) &&
SystemInfo.graphicsShaderLevel >= 30 &&
SystemInfo.graphicsMultiThreaded &&
SystemInfo.supportsShadows &&
SystemInfo.supportsInstancing &&
SystemInfo.supports32bitsIndexBuffer
)
{
return eQualityLevel.Ultra;
}
else if (SystemInfo.processorFrequency >= 2000 &&
SystemInfo.processorCount >= 4 &&
SystemInfo.systemMemorySize >= (4 * 1024) &&
SystemInfo.graphicsMemorySize >= (1 * 1024) &&
SystemInfo.graphicsShaderLevel >= 20
)
{
return eQualityLevel.High;
}
else if (SystemInfo.processorFrequency >= 1500 &&
SystemInfo.processorCount >= 2 &&
SystemInfo.systemMemorySize >= (2 * 1024) &&
SystemInfo.graphicsMemorySize >= (512) &&
SystemInfo.graphicsShaderLevel >= 10
)
{
return eQualityLevel.Middle;
}
else
{
return eQualityLevel.Low;
}
}
// 设置 当前品质等级
private static void _SetCurLevel(eQualityLevel level)
{
_SetAntiAliasing(level);
_SetResolution(level);
_SetTexMipmapOffset(level);
_SetShadow(level);
_SetLODBias(level);
_SetGraphicsTier(level);
_SetShaderLOD(level);
_SetGlobalShaderKW(level);
}
// 设置 AA
private static void _SetAntiAliasing(eQualityLevel level)
{
if (level >= eQualityLevel.High)
{
QualitySettings.antiAliasing = srcAntiAliasing;
}
else
{
QualitySettings.antiAliasing = 0;
}
}
// 设置分辨率
private static void _SetResolution(eQualityLevel level)
{
// jave.lin : BRP(Built-In Rendering Pipeline) 中
// 需要对应的 Camera 开启 AllowDynamicResolution 后才能生效
switch (level)
{
case eQualityLevel.Low:
QualitySettings.resolutionScalingFixedDPIFactor = 0.75f;
break;
case eQualityLevel.Middle:
QualitySettings.resolutionScalingFixedDPIFactor = 0.85f;
break;
case eQualityLevel.High:
QualitySettings.resolutionScalingFixedDPIFactor = 0.85f;
break;
case eQualityLevel.Ultra:
QualitySettings.resolutionScalingFixedDPIFactor = 1.00f;
break;
}
}
// 设置 Tex 纹理 mipmap offset
private static void _SetTexMipmapOffset(eQualityLevel level)
{
switch (level)
{
case eQualityLevel.Low:
QualitySettings.masterTextureLimit = DeviceAdapterLevel < eQualityLevel.High ? 3 : 2;
break;
case eQualityLevel.Middle:
QualitySettings.masterTextureLimit = DeviceAdapterLevel < eQualityLevel.High ? 2 : 1;
break;
case eQualityLevel.High:
QualitySettings.masterTextureLimit = 0;
break;
case eQualityLevel.Ultra:
QualitySettings.masterTextureLimit = 0;
break;
}
}
// 设置阴影
private static void _SetShadow(eQualityLevel level)
{
switch (level)
{
case eQualityLevel.Low:
case eQualityLevel.Middle:
//QualitySettings.shadows = ShadowQuality.Disable; // jave.lin : 有 BUG,会导致,Animator 组件中的 culling mode 不是 always animated 的对象超出屏幕的画,会被自动停止掉
// 所以下面使用 shadowDistance 来替代关闭
QualitySettings.shadowDistance = 0;
break;
case eQualityLevel.High:
QualitySettings.shadows = srcShadows;
QualitySettings.shadowResolution = ShadowResolution.Low;
QualitySettings.shadowDistance = 70;
break;
case eQualityLevel.Ultra:
QualitySettings.shadows = srcShadows;
QualitySettings.shadowResolution = ShadowResolution.High;
QualitySettings.shadowDistance = 100;
break;
}
}
// 设置 LOD 偏移
private static void _SetLODBias(eQualityLevel level)
{
switch (level)
{
case eQualityLevel.Low:
QualitySettings.lodBias = 0.5f;
break;
case eQualityLevel.Middle:
QualitySettings.lodBias = 0.75f;
break;
case eQualityLevel.High:
case eQualityLevel.Ultra:
QualitySettings.lodBias = 1.0f;
break;
}
}
// 设置 GraphicsTier 的层级
private static void _SetGraphicsTier(eQualityLevel level)
{
switch (level)
{
case eQualityLevel.Low:
case eQualityLevel.Middle:
Graphics.activeTier = GraphicsTier.Tier1;
break;
case eQualityLevel.High:
Graphics.activeTier = GraphicsTier.Tier2;
break;
case eQualityLevel.Ultra:
Graphics.activeTier = GraphicsTier.Tier3;
break;
}
}
// 设置 Shader LOD
private static void _SetShaderLOD(eQualityLevel level)
{
switch (level)
{
case eQualityLevel.Low:
Shader.globalMaximumLOD = (int)eShaderLOD.VeryLow;
break;
case eQualityLevel.Middle:
Shader.globalMaximumLOD = (int)eShaderLOD.Low;
break;
case eQualityLevel.High:
Shader.globalMaximumLOD = (int)eShaderLOD.Middle;
break;
case eQualityLevel.Ultra:
Shader.globalMaximumLOD = (int)eShaderLOD.High;
break;
default:
Shader.globalMaximumLOD = (int)eShaderLOD.UnLimit;
break;
}
}
// 设置全局Shader Keyword
private static void _SetGlobalShaderKW(eQualityLevel level)
{
switch (level)
{
case eQualityLevel.Low:
case eQualityLevel.Middle:
Shader.DisableKeyword("_SOFT_PARTICLE_ON");
break;
case eQualityLevel.High:
case eQualityLevel.Ultra:
Shader.EnableKeyword("_SOFT_PARTICLE_ON");
break;
}
}
}
// jave.lin : 后效基类
public class PPBasic : MonoBehaviour { }
// jave.lin : Bloom 后效
public class BloomPP : PPBasic
{
// jave.lin : start 时 先处理,处理当前品质
// 然后监听 品质变化的时间
private void Start()
{
OnQualityLevelChanged(GameQualitySettings.GraphicsLevel);
GameQualitySettings.onLevelChanged -= OnQualityLevelChanged;
GameQualitySettings.onLevelChanged += OnQualityLevelChanged;
}
// jave.lin : 销毁时记得删除回调
private void OnDestroy()
{
GameQualitySettings.onLevelChanged -= OnQualityLevelChanged;
}
private void OnQualityLevelChanged(eQualityLevel ql)
{
// jave.lin : 当 品质等级大于或等于高时,才开启 Bloom 后效
enabled = ql >= eQualityLevel.High;
}
}
[출처] https://blog.csdn.net/linjf520/article/details/123546253
반응형
'Unity3D > Script' 카테고리의 다른 글
[펌] OcclusionCulling2D (0) | 2024.03.14 |
---|---|
[최적화] Automatic quality settings (0) | 2024.01.19 |
[ChatGPT] Multi-Key Dictionary in Unity? (0) | 2023.08.07 |
[Build] 빌드 시, Builtin 되는 AssetBundle 중 현재 Platform의 AssetBundle만 빌트인 되도록 하기 (0) | 2023.01.18 |
[링크] 유니티 - Scripting Define Symbol 스크립트로 제어하기 (0) | 2022.07.20 |