Skip to content

自定义缩放器

您可以通过创建专有的缩放器 (Scalers) 毫不费力地扩展 Web Adaptive Performance 系统。如果您希望动态优化特定机制,这将很有帮助:例如,当 FPS 下降时,降低人群密度、禁用繁重的着色器或简化敌人的 AI。

WebAP 架构与 Unity AP

在 Unity 的官方包中,创建自定义缩放器需要复杂的配置:生成 ScriptableObject,通过接口链接设置,以及在两个互斥的工作流程中选择一个。

在 WebAP 中,一切都在即插即用 (Plug-and-Play) 的基础上运行。
您只需编写一个继承自 WebScalerBase 的单一 C# 脚本。插件核心自动检测您的类并将其填充到 Project Settings 窗口中的全局缩放器列表中,您可以在其中直观地启用它并配置其参数。

通过示例学习

了解如何编写自定义缩放器的最佳方法是研究内置的缩放器。所有基础缩放器(分辨率、阴影、LOD 等)的源代码都在您的项目中:
WebAdaptivePerformance/Runtime/Scalers/

自定义缩放器模板

要创建您的缩放器,请完成 3 个简单的步骤:

  1. 继承 WebScalerBase 类。
  2. 在构造函数中定义默认参数(TargetVisual ImpactMax Level)。
  3. 重写生命周期方法:OnEnabled()OnDisabled()OnLevel()

IL2CPP 代码剥离 (对 WebGL 至关重要)

为 WebGL 构建项目时,IL2CPP 编译器会积极地剥离“死”代码。由于插件通过反射动态实例化您的自定义缩放器,编译器会认为它们未被使用并将它们从构建中删除。

请始终将 [UnityEngine.Scripting.Preserve] 属性 附加到您的自定义类上方。这保证了缩放器将在发布构建中发挥作用。

示例:纹理质量缩放器

下面是创建一个降低纹理分辨率 (Mipmap Limit) 的缩放器的全面示例。

csharp
using System;
using UnityEngine;
using GrindsetStudios.WebAdaptivePerformance.Scalers;

// 对于 UI 显示 (Project Settings) 和代码剥离保护 (IL2CPP),属性是强制性的
[Serializable]
[UnityEngine.Scripting.Preserve] 
public sealed class WebTextureQualityScaler : WebScalerBase
{
    // 专门用于存储用户初始设置的变量
    private int _defaultTextureLimit;

    public WebTextureQualityScaler()
    {
        // 指定此缩放器降低视频卡上的负载
        _target = ScalerTarget.GPU; 
        
        // 降低纹理分辨率非常明显,因此设置为 High
        _visualImpact = ScalerVisualImpact.High;
        
        // 建立 3 个纹理降级步骤:Half (1), Quarter (2), Eighth (3)
        _maxLevel = 3; 
    }

    // 在游戏启动或插件激活时调用
    protected override void OnEnabled()
    {
        // 缓存原始值以在缩放器停用时恢复它
        _defaultTextureLimit = QualitySettings.globalTextureMipmapLimit;
        ApplyScale();
    }

    // 在插件停用或手动删除缩放器时调用
    protected override void OnDisabled()
    {
        // 安全地将游戏恢复到其初始状态
        QualitySettings.globalTextureMipmapLimit = _defaultTextureLimit;
    }

    // 每次索引器决定更改质量级别时调用
    protected override void OnLevel()
    {
        ApplyScale();
    }

    private void ApplyScale()
    {
        // ScaleChanged() 方法重新计算缩放,如果它发生偏移则返回 true
        if (ScaleChanged())
        {
            // 我们故意避免在计算中使用默认值
            // 以防止图形已经处于最低级别时发生冲突。
            // 
            // globalTextureMipmapLimit 参数接受整数: 
            // 0 (Full), 1 (Half), 2 (Quarter), 3 (Eighth)。
            // 我们的 CurrentLevel (从 0 到 3) 完美地符合此逻辑。
            QualitySettings.globalTextureMipmapLimit = CurrentLevel;
        }
    }
}

保存此脚本后,导航至 Edit -> Project Settings -> Adaptive Performance (Web)。展开 Scalers 选项卡,您将在可用模块列表中看到您的 Texture Quality

对象搜索优化

OnLevel() 方法可能会被频繁调用(在冷却触发期间)。永远不要在其中利用诸如 GameObject.Find()GetComponent() 之类的繁重方法。始终在 OnEnabled() 方法中定位并缓存所需的组件。