Как я могу контролировать изменения звука, сделанные в главном меню, которые будут применяться также к настройкам звука в игровой сцене?

#c# #unity3d #audio

#c# #unity3d #Аудио

Вопрос:

У меня есть две сцены: игра и главное меню. У меня есть два ползунка в главном меню, я могу управлять громкостью музыки и громкостью sfx и сохранять изменения, и все работает нормально.

Для этого в главном меню есть собственный аудиомикшер, а в игровой сцене — свой собственный аудиомикшер. Как я могу применить изменения, которые я делаю в громкости / с главного меню, чтобы они применялись также к громкостям звукового микшера игровой сцены?

Это скриншот аудиомикшера в игровой сцене, я добавил пустой игровой объект, назовите его Game Audio :

Настройки звука в игре

Те же настройки копируют настройки для звукового микшера сцены главного меню :

Скриншот настроек звука в главном меню :

настройки звука в главном меню

Позже я изменю музыкальный клип и эффекты sfx в игровой сцене. Причина использования двух микшеров для каждого из сцен главного меню и игры заключается в том, чтобы иметь возможность управлять музыкой и sfx индивидуально в каждой сцене.

Настройки этого скрипта находятся в сцене главного меню и управляют громкостью музыки и слайдеров sfx :

 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;
using TMPro;
using System;
using UnityEngine.Events;
using System.Linq;

public class Settings : MonoBehaviour
{
    public AudioMixer audioMixer;
    public TMP_Dropdown resolutionDropdown;
    public TMP_Dropdown qualityDropdown;
    public Text musicText;
    public Text sfxText;
    public Slider[] audioSliders;
    public Toggle fullScreenToggle;

    private Resolution[] resolutions;

    private void Awake()
    {
        resolutionDropdown.onValueChanged.AddListener(new UnityAction<int>(index =>
        {
            PlayerPrefs.SetInt("resolutionvalue", resolutionDropdown.value);
            PlayerPrefs.Save();

        }));

        qualityDropdown.onValueChanged.AddListener(new UnityAction<int>(index =>
        {
            PlayerPrefs.SetInt("qualityvalue", qualityDropdown.value);
            PlayerPrefs.Save();

        }));

        fullScreenToggle.onValueChanged.AddListener(new UnityAction<bool>(index =>
        {
            PlayerPrefs.SetInt("fullscreen", boolToInt(fullScreenToggle.isOn));
            PlayerPrefs.Save();

        }));
    }

    private void Start()
    {
        qualityDropdown.value = PlayerPrefs.GetInt("qualityvalue");

        var resolutions = Screen.resolutions.Where(resolution => resolution.refreshRate == 60).ToArray();
        resolutionDropdown.ClearOptions();

        List<string> options = new List<string>();

        int currentResolutionIndex = 0;
        for(int i = 0; i < resolutions.Length; i  )
        {
            string option = resolutions[i].width   " x "   resolutions[i].height;
            options.Add(option);

            if(resolutions[i].width == Screen.currentResolution.width amp;amp;
                resolutions[i].height == Screen.currentResolution.height)
            {
                currentResolutionIndex = i;
            }
        }

        resolutionDropdown.AddOptions(options);
        resolutionDropdown.value = PlayerPrefs.GetInt("resolutionvalue", currentResolutionIndex);
        resolutionDropdown.RefreshShownValue();

        float musicvolume = PlayerPrefs.GetFloat("musicvolume");
        float sfxvolume = PlayerPrefs.GetFloat("sfxvolume");

        musicText.text = musicvolume.ToString();
        sfxText.text = sfxvolume.ToString();
        audioSliders[0].value = musicvolume / 100f;
        audioSliders[1].value = sfxvolume / 100f;

        fullScreenToggle.isOn = intToBool(PlayerPrefs.GetInt("fullscreen", 0));
        
    }

    public void SetResolution(int resolutionIndex)
    {
        if (resolutions != null)
        {
            Resolution resolution = resolutions[resolutionIndex];
            Screen.SetResolution(resolution.width, resolution.height, Screen.fullScreen);
        }
    }

    public void SetMusicVolume(float volume)
    {
        audioMixer.SetFloat("musicvol", Mathf.Log10(volume) * 20);
        musicText.text = Math.Round(volume * 100, MidpointRounding.AwayFromZero).ToString();

        PlayerPrefs.SetFloat("musicvolume", (float)Math.Round(volume * 100, MidpointRounding.AwayFromZero));
    }

    public void SetSfxVolume(float volume)
    {
        audioMixer.SetFloat("sfxvol", Mathf.Log10(volume) * 20);
        sfxText.text = Math.Round(volume * 100, MidpointRounding.AwayFromZero).ToString();

        PlayerPrefs.SetFloat("sfxvolume", (float)Math.Round(volume * 100, MidpointRounding.AwayFromZero));
    }

    public void SetQuality(int qualityIndex)
    {
        QualitySettings.SetQualityLevel(qualityIndex);
    }

    public void SetFullscreen(bool isFullscreen)
    {
        Screen.fullScreen = isFullscreen;        
    }

    int boolToInt(bool val)
    {
        if (val)
            return 1;
        else
            return 0;
    }

    bool intToBool(int val)
    {
        if (val != 0)
            return true;
        else
            return false;
    }
} 
 

Теперь, когда я нахожусь в сцене главного меню, игровая сцена также все еще загружена, и я хочу, чтобы при изменении громкости / громкости в главном меню это также повлияло на звук игры. Не та же музыка и sfx в главном меню, что и в игре, а просто знать, что я изменил громкость / с, чтобы это повлияло и на игровую сцену.

Этот скрипт находится в игровой сцене. В массиве objsToDisable у меня есть 3 объекта, которые я отключаю / включаю, и в этом массиве я хочу иметь возможность отключать / включать звук игры. Я выставлял как музыку, так и sfx в игровом аудиомикшере, но не уверен, как настроить плавающий режим игрового аудиомикшера? Куда мне добавить значение с плавающей точкой или как мне использовать его в этом скрипте?

 using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class BackToMainMenu : MonoBehaviour
{
    public GameObject[] objsToDisable;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (Time.timeScale == 0)
            {
                DisableEnableUiTexts(true);
                SceneManager.UnloadSceneAsync(0);
                Cursor.visible = false;
                Time.timeScale = 1;
            }
            else
            {
                Time.timeScale = 0;
                MenuController.LoadSceneForSavedGame = false;
                SceneManager.LoadScene(0, LoadSceneMode.Additive);
                SceneManager.sceneLoaded  = SceneManager_sceneLoaded;

                Cursor.visible = true;
            }
        }
    }

    private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
    {
        DisableEnableUiTexts(false);
    }

    private void DisableEnableUiTexts(bool enabled)
    {
        foreach (GameObject go in objsToDisable)
        {
            if (go.name == "Cameras")
            {
                foreach(Transform child in go.transform)
                {
                    if(child.name == "Main Camera")
                    {
                        if (enabled == false)
                        {
                            child.GetComponent<Camera>().enabled = false;
                        }
                        else
                        {
                            child.GetComponent<Camera>().enabled = true;
                        }
                    }
                }
            }
            else
            {
                go.SetActive(enabled);
            }
        }
    }
}
 

Комментарии:

1. Почему вы используете не один аудиомикшер, а разные группы?

Ответ №1:

Вы можете использовать DontDestroyOnLoad. Если вы вызовете это в monobehaviour, подключенном к аудиомикшеру, он останется на всех сценах и сохранит заданную ему переменную. Если вы не вызовете destroy вручную. Теперь у вас есть 2 аудиомикшера. Вы можете получить пользовательское значение из старого аудиомикшера и установить его для аудиомикшера основной сцены. Затем удалите старый. Также вы должны отключить звук микшера, подключенного к DontDestroyOnLoad, чтобы одновременно был активен только 1 источник звука.