ProjectSettings > Audio > Global Volume


ProjectSettings の Audio には、オーディオのボリュームを調整できる Global Volume がある。一方ランタイムで操作できるボリュームには static 変数の、AudioListener.volume がある。
この両方はどうやら一緒っぽい。
AudioListener.volume が再生する度に Global Volume の値にリセットされているっぽい。
Unity での音が大きい場合ここを下げておくと便利なので、それを Editor 拡張からどうやればいいか調べてみました。

まずはエディタ拡張用の Slider。

<engine:Slider low-value="0" high-value="1" value="1" name="audioVolume" />

次に EditorWindow を継承したクラスでまずは Slider のイベント取得。
そして、スライダーが変わるごとに ProjectSettings の Audio の Global Volume を書き換え。
なぜか再生するたびに uxml 側の Slider が戻ってしまうので、再生時に設定されている値を入れ直す的な流れでできました。

/// <summary>
/// 静的コンストラクタ。
/// </summary>
static Lesson01Utility()
{
    EditorApplication.playmodeStateChanged += PlayModeStateChanged;
}


/// <summary>
/// OnEnable.
/// </summary>
public void OnEnable()
{
    VisualElement root = rootVisualElement;
    VisualTreeAsset visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/UXML/***.uxml");
    VisualElement labelFromUXML = visualTree.CloneTree();
    root.Add(labelFromUXML);

    AudioVolumeSlider = root.Query<Slider>("audioVolume").First();
    AudioVolumeSlider.RegisterValueChangedCallback<float>(OnAudioVolumeChanged);
}

/// <summary>
/// ProjectSettings > Audio > Global Volume の変更。
/// </summary>
private static void OnAudioVolumeChanged(ChangeEvent<float> evt)
{
    SetAudioGlobalVolume(evt.newValue);
}

/// <summary>
/// ProjectSettings > Audio > Global Volume の変更。
/// </summary>
private static void OnAudioVolumeChanged(ChangeEvent<float> evt)
{
    SetAudioGlobalVolume(evt.newValue);
}

private static void SetAudioGlobalVolume(float volume)
{
    Object audioMmanager = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/AudioManager.asset").FirstOrDefault();
    SerializedObject audioManagerObject = new SerializedObject(audioMmanager);
    SerializedProperty globalVolumeProperty = audioManagerObject.FindProperty("m_Volume");

    globalVolumeProperty.floatValue = volume;
    audioManagerObject.ApplyModifiedProperties();
}

private static float GetAudioGlobalVolume()
{
    Object audioMmanager = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/AudioManager.asset").FirstOrDefault();
    SerializedObject audioManagerObject = new SerializedObject(audioMmanager);
    SerializedProperty globalVolumeProperty = audioManagerObject.FindProperty("m_Volume");

    return globalVolumeProperty.floatValue;
}

/// <summary>
/// 以前の状態で再生されていたか。
/// </summary>
private static bool WasPlaying = false;

/// <summary>
/// 再生モードが変更された。
/// </summary>
private static void PlayModeStateChanged()
{
    if (EditorApplication.isPlaying && EditorApplication.isPlaying != WasPlaying)
    {
        AudioVolumeSlider.value = GetAudioGlobalVolume();
        WasPlaying = EditorApplication.isPlaying;
    }
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です