Unity - 画质设置


Show me Your Code, Talk Is Cheap.

以前自己写的类,现在重新写一份 代码

便于日后直接搬运使用,代码都是相当简单,都是直接调用 unity 的 API 设置即可,可以理解为就是搬运而已


环境

Unity : 2018.2.11f1
Pipeline : BRP

改用在:URP 也是很简单(部分 API 修改一下即可)


GameQualitySettings

// 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;
    }
}

猜你喜欢

转载自blog.csdn.net/linjf520/article/details/123546253