Skip to content

カスタムスケーラー (Custom Scalers)

カスタムスケーラーを作成することで、Web Adaptive Performanceシステムを簡単に拡張できます。これは、特定のゲームメカニズムを動的に最適化したい場合に有利です。例えば、FPSが低下したときに群衆の密度を減らしたり、重いシェーダーを無効にしたり、敵のAIを簡略化したりすることができます。

WebAP vs Unity AP アーキテクチャ

公式のUnityパッケージでは、カスタムスケーラーの作成には複雑な設定が必要です:ScriptableObject の生成、インターフェースを介した設定の相互接続、および互いに排他的な2つのワークフローのいずれかの選択。

WebAPでは、すべてがプラグアンドプレイ (Plug-and-Play) で機能します。
WebScalerBase を継承する単一のC#スクリプトを記述するだけです。プラグインコアは自動的にクラスを発見し、Project Settings ウィンドウ内のグローバルスケーラーリストに追加します。そこで、スケーラーを有効にし、視覚的にパラメータを構成できます。

例から学ぶ

カスタムスケーラーの書き方を理解する最良の方法は、組み込みのものを調べることです。すべてのベーススケーラー(Resolution、Shadows、LODなど)のソースコードは、プロジェクトの以下の場所にあります:
WebAdaptivePerformance/Runtime/Scalers/

カスタムスケーラーのテンプレート

スケーラーを作成するには、3つの簡単な手順を完了します:

  1. WebScalerBase からクラスを継承します。
  2. コンストラクタでデフォルトのパラメータ(TargetVisual ImpactMax Level)を設定します。
  3. ライフサイクルメソッドである OnEnabled()OnDisabled()、および OnLevel() をオーバーライドします。

IL2CPP ストリッピング (WebGLに不可欠)

WebGL用のプロジェクトをビルドするとき、IL2CPPコンパイラは「デッドコード (dead code)」を積極的に削除 (strip) します。プラグインはリフレクション (Reflection) を介してカスタムスケーラーを動的にインスタンス化するため、コンパイラはそれらが未使用であると見なし、ビルドから削除してしまいます。

カスタムクラスには必ず [UnityEngine.Scripting.Preserve] 属性を付与してください。 これにより、スケーラーがリリースビルドで確実に機能することが保証されます。

例:テクスチャ品質スケーラー (Texture Quality Scaler)

以下は、テクスチャの解像度(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つのステップを設定します:半分 (1)、4分の1 (2)、8分の1 (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 (フル), 1 (半分), 2 (4分の1), 3 (8分の1)。
            // 私たちの CurrentLevel (0 から 3) は、この論理と完全に一致します。
            QualitySettings.globalTextureMipmapLimit = CurrentLevel;
        }
    }
}

このスクリプトを保存したら、Edit -> Project Settings -> Adaptive Performance (Web) に移動します。Scalers タブを展開すると、利用可能なモジュールのリストに Texture Quality が表示されます。

オブジェクト検索の最適化

OnLevel() メソッドは頻繁に呼び出される可能性があります(クールダウンのトリガー中)。その内部で GameObject.Find()GetComponent() などの重いメソッドを決して使用しないでください。常に OnEnabled() メソッドで必要なコンポーネントを見つけてキャッシュするようにしてください。