Unity | AudioSource.mute не работает

308
27 декабря 2021, 22:20

У меня есть функция (прикручена к нажатию кнопки), которая должна включать/отключать весь звук на сцене (ну и сохранять наличие/отсутствие звука в PlayerPrefs). Она работает абсолютно на рандом, хочет - только работает mute = true, хочет - только mute = false (это меняется при обновлении скрипта). Я никак не могу понять почему.

Функция: (MusicBtn - кнопка звука, нужна только для смены иконки)

// using System.Linq
public void OnOffMusic()
{
    if (PlayerPrefs.GetString("Music") == "off")
    {
        PlayerPrefs.SetString("Music", "on");            
        MusicBtn.image.sprite = MusicOn;
    }
    else
    {
        PlayerPrefs.SetString("Music", "off");
        MusicBtn.image.sprite = MusicOff;
    }
    FindObjectsOfType<AudioSource>().All(audio => audio.mute != audio.mute);
}

Кнопка:

!!! Сразу 5 оговорок:

  1. Я могу свободно в редакторе в рантайм поменять значение mute на нужное и всё работает.
  2. Я пробовал писать mute = false и mute = true явно.
  3. Я делал отладку и FindObjectsOfType правильно находит все аудио
  4. Я пробовал использовать ожидание по примерам в интернете (класс Extensions)
  5. В Start() я проверяю существование в PlayerPrefs "Music"

Extensions:

public static IEnumerator Mute(this AudioSource audioSource)
{
    yield return new WaitForSeconds(0.01f);
    audioSource.mute = true;
}
public static IEnumerator Unmute(this AudioSource audioSource)
{
    yield return new WaitForSeconds(0.01f);
    audioSource.mute = false;
}

Start():

if (PlayerPrefs.HasKey("Music"))
    {
        if (PlayerPrefs.GetString("Music") == "off")
        {
            FindObjectsOfType<AudioSource>().All(audio => audio.mute = true);
            MusicBtn.image.sprite = MusicOn;
        }
    }
    else
    {
        PlayerPrefs.SetString("Music", "on");
    }

Что делать???

Answer 1

Вы написали расширяющий метод используя итератор, в качестве возвращаемого значения:

public static IEnumerator Mute(this AudioSource audioSource)
{
    yield return new WaitForSeconds(0.01f);
    audioSource.mute = true;
}

Поэтому при при вызове audioSource.Mute() у вас не запустится корутина, а просто вернётся итератор, который вам самостоятельно придётся "двигать", чтобы поток выполнения кода дошёл до вашего заветного

audioSource.mute = true;

Решением будет заменить audioSource.Mute() на

StartCoroutine(audioSource.Mute());

В принципе, если у вас уже всё так и написано и я несу очевидные вещи, то прошу прислать больше данных.

Так же советую проверить массив FindObjectsOfType<AudioSource>() на наличие в нём элементов.

READ ALSO
Назначил кнопке обработчик событий, но ничего не происходит. WPF

Назначил кнопке обработчик событий, но ничего не происходит. WPF

Хочу сделать свою программу многостраничнойДля этого я назначил кнопке событие по переключению страниц

96
Сократить код обращения к одинаковым свойствам классов, когда они реализованы разными базовыми классами/интерфейсами?

Сократить код обращения к одинаковым свойствам классов, когда они реализованы разными базовыми классами/интерфейсами?

Пишу простой tweener на UnityДвижок предоставляет классы (компоненты) для рендера, и у тех, что я использую есть свойство color, но эти классы не наследуются...

201
как мне перехватить этот вид исключения

как мне перехватить этот вид исключения

Как в laravel сделать если не авторизован пользователь и вызвать Auth::user()->id; то возвращается ошибка Trying to get property of non-object как ее заменить на свое...

128
Условие на значение атрибута WooCommerce

Условие на значение атрибута WooCommerce

Подскажите, пожалуйста, есть ли возможность задать условие когда определенный атрибут данного товара равен чему-то, то вывести изображение,...

188