LoginSignup
2
0

【AudioMixer】exposed parametersの操作クラスを自動生成する

Last updated at Posted at 2023-12-17

この記事はUnity Advent Calendar 2023 18日目の記事です。
昨日はSource Generatorでプロパティを自動実装してみたでした。
明日は Source GeneratorでNullObjectを自動生成する が公開されます!

なんの記事?

Unity標準のAudioMixerは非常に便利な機能ですが、

スクリプトから各機能にアクセスするためには、exposed parametersを作成し、

文字列でそれを読み取って制御しなければなりません。

せっかく柔軟な音声コントロールを提供しているのに、

文字列が増えたり減ったりする度にスクリプト編集が必要になると 柔軟性を活かしきれません。

そこで、自動でコントローラークラスを生成してくれるエディタ拡張 を作りました!

導入方法

  • 以下URL右側のReleaseページから unitypackage をDLして使ってください。

利用方法

起動

メニューバーのTools>GenerateCode>AudioMixerControllerから起動します。

img_5.png

起動すると以下のようなウインドウが表示されます。

AudioMixerをアタッチして、ボタンを押すと、設定位置にコードが自動生成されます!

img_6.png

初期設定では、ControllerはAssets/Scripts/Sound/AudioMixerController.csとして生成されます。

また、interfaceはAssets/Scripts/Sound/Interface/IAudioMixerControllable.csとして生成されます。

Asyncメソッド生成は、DotweenUniTaskに依存しています。

標準設定のままAsyncメソッドを利用したい場合には、各パッケージを導入しておいてください。

実装メソッド

自動で実装されるメソッドを以下に紹介します。

標準で以下の3種類のメソッドが生成されます。

引数のExposedPropertyは自動実装されたEnumです。
AudioMixerに登録されているExposedPropertyが自動でEnumとして生成されます。
実行時に操作するExposedPropertyを指定してください。

//指定のExposedPropertyの値を変更します。
//仮にMasterVolumeの実装は以下のようになります。
public void ExposedPropertyChange(float value ,ExposedProperty prop) 
{ 
    switch(prop)
    {
        case ExposedProperty.MasterVolume:
            _audioMixer.SetFloat("MasterVolume", value);
            break;
    }
}

//指定のExposedPropertyの値を起動時の値に戻します。
//仮にMasterVolumeの実装は以下のようになります。
public void ExposedPropertyReset(float value ,ExposedProperty prop)
{

    switch(prop)
    {
        //_originalMasterVolumeは初期値です。Awakeメソッド、またはコンストラクタで格納されます。
        case ExposedProperty.MasterVolume:
            _audioMixer.SetFloat("MasterVolume", _originalMasterVolume);
            break;
    }
}

//指定のExposedPropertyの現在の値を取得します。
//取得に成功するとtrueが返ります。また、out valueに現在の値が返ります。
//仮にMasterVolumeの実装は以下のようになります。
public bool GetExposedProperty(out float value ,ExposedProperty prop)
{
    switch(prop)
    {
        case ExposedProperty.MasterVolume:
            return _audioMixer.GetFloat("MasterVolume", out value);
            break;
        default :
            value = 0;
            return false;
    }
}

Asyncメソッドを要求した場合は、追加で以下の2種類のメソッドが生成されます。

public async UniTask ExposedPropertyChangeAsync(float value, CancellationToken token, float duration ,ExposedProperty prop)
{
    //指定のExposedPropertyの値をduration分の時間をかけて変更します。
    //仮にMasterVolumeの実装は以下のようになります。
   switch(prop)
    {
        case ExposedProperty.MasterVolume:
            await _audioMixer.DOSetFloat("MasterVolume", value, duration).WithCancellation(token);
            break;
    }
}

public async UniTask ExposedPropertyResetAsync(CancellationToken token, float duration ,ExposedProperty prop)
{
    //指定のExposedPropertyの値を、duration分の時間をかけて元の値に戻します。
    //仮にMasterVolumeの実装は以下のようになります。
       switch(prop)
    {
        case ExposedProperty.MasterVolume:
            await _audioMixer.DOSetFloat("MasterVolume", _originalMasterVolume, duration).WithCancellation(token);
    }
}

Asyncメソッド生成は、DotweenUniTaskに依存しています。

この他にも、各ExposedPropertyの値を変更するメソッドが自動生成されます。

詳細は生成されたコードを参照してください。

生成コードの設定変更

生成コードの設定は以下ファイルを書き換えることで変更可能です。

Assets/Plugins/GenerateAudioMixerController/Editor/AudioMixerControllerGenerationSetting.cs

各設定項目の解説を以下に解説します。コードと併せて確認してください。

よく使う設定

isMonoBehaviourAndSerializeAudioMixer

ControllerクラスをMonoBehaviourとして実装するかを指定します。
trueの場合はMonoBehaviour継承クラスとして生成し、AudioMixerをシリアライズドフィールドで受付けます。

falseの場合にはピュアクラスとして生成し、コンストラクタ引数でAudioMixerを受け取ります。

classNameSpace

Controllerクラスを配置するNamespaceを指定します。

className

Controllerクラスのクラス名を指定します。

GenerateClassFilePath()

Controllerクラスを保存するファイルパスを指定します。

{className}部分が、上記のclassNameの値に置換されます。

interfaceNameSpace

InterfaceのNamespaceを指定します。

interfaceName

Interfaceの名前を指定します。

あまり使わない設定

以降の情報は、より便利に使うための詳細情報です。
標準設定で使う分には把握する必要はありません。
生成されるメソッド自体を変更するような場合には把握する必要があります。

requireOverrideFiles

同名ファイルが既にある場合に上書きするかを指定します。

同名クラスが重複するとエラーになるので、true にして常に上書きする運用を推奨します。

GenerateClassImportNameSpace()

Controllerクラスにusingステートメントで宣言するNameフィールドを指定します。

AsyncMethodの生成が要求された場合、以下の箇所でDotWeenとUniTask関連のusingステートメントが生成される設定になっています。

他の方法でAsyncメソッドを実装する場合は書き換えてください。

            if (requireAsyncMethod) 
                classImportNameSpace += @$"
using System.Threading;
using Cysharp.Threading.Tasks;
using DG.Tweening;
";

また、interface の実装が要求されており、
interfaceのネームスペースが切られている場合は以下の箇所で自動的にusing宣言します。

            if (requireInterfaceGeneration && !string.IsNullOrEmpty(interfaceNameSpace)) 
                classImportNameSpace += @$"
using {interfaceNameSpace};";

GenerateInterfaceFilePath()

Interfaceを保存するファイルパスを指定します。

{interfaceName}部分が、interfaceNameの値に置換されます。

GenerateInterfaceImportNameSpace()

Interfaceのusingステートメントを指定します。

additionalClasVariableDeclaration

Controllerクラスのメンバ変数として追加で宣言したいことがあれば記入します。

GenerateChangeMethodName(string propertyName)

ExposedPropertyの値を変更するメソッド名を指定します。Interfaceの生成に利用されます。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateChangeMethodCall(string propertyName)

ExposedPropertyの値を変更するメソッドをコールする記載を指定します。

共通メソッドであるExposedPropertyChangenの生成に利用されます。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateChangeMethod(string propertyName)

個別のExposedPropertyの値を変更するメソッドの実装を指定します。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateResetMethodName(string propertyName)

ExposedPropertyの値をリセットするメソッド名を指定します。Interfaceの生成に利用されます。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateResetMethodCall(string propertyName)

ExposedPropertyの値をリセットするメソッドをコールする記載を指定します。

共通メソッドであるExposedPropertyResetの生成に利用されます。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateResetMethod(string propertyName)

個別のExposedPropertyの値をリセットするメソッドの実装を指定します。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateGetMethodName(string propertyName)

個別のExposedPropertyの値を取得するメソッドの名前を指定します。Interfaceの生成に利用されます。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateGetMethodCall(string propertyName)

個別のExposedPropertyの値を取得するメソッドをコールする記載を指定します。

共通メソッドであるGetExposedPropertyの生成に利用されます。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateGetMethod(string propertyName)

個別のExposedPropertyの値を取得するメソッドの実装を指定します。

引数のpropertyNameには、ExposedPropertyの名前が渡されます。

GenerateChangeAsyncMethodName(string propertyName)

GenerateChangeMethodNameと同様ですが、Asyncメソッド用です。

GenerateChangeAsyncMethodCall(string propertyName)

GenerateChangeMethodCallと同様ですが、Asyncメソッド用です。

GenerateChangeAsyncMethod(string propertyName)

GenerateChangeMethodと同様ですが、Asyncメソッド用です。

GenerateResetAsyncMethodName(string propertyName)

GenerateResetMethodNameと同様ですが、Asyncメソッド用です。

GenerateResetAsyncMethodCall(string propertyName)

GenerateResetMethodCallと同様ですが、Asyncメソッド用です。

GenerateResetAsyncMethod(string propertyName)

GenerateResetMethodと同様ですが、Asyncメソッド用です。

変更できない変数

requireAsyncMethod

Asyncメソッドを生成するかを指定します。
エディタ上のチェックボックスよって値が上書きされるため、コードからは変更できません。

requireInterfaceGeneration

Interfaceを生成するかを指定します。
エディタ上のチェックボックスよって値が上書きされるため、コードからは変更できません。

おわりに

ここまで読んでくださってありがとうございました。
利用に際して不明な点などありましたら、コメントや、XのDMにてご連絡ください。

開発の一助になれば幸いです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0