#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 источник звука.