game: format scripts

This commit is contained in:
Mark Joshwel 2024-07-04 04:37:15 +08:00
parent 4aa6329bdf
commit 73d46c302b
6 changed files with 180 additions and 176 deletions

View file

@ -8,39 +8,15 @@
using UnityEngine; using UnityEngine;
/// <summary> /// <summary>
/// singleton class for handling audio in the game /// singleton class for handling audio in the game
/// </summary> /// </summary>
public class AudioManager : MonoBehaviour public class AudioManager : MonoBehaviour
{ {
/// <summary> /// <summary>
/// singleton pattern: define instance field for accessing the singleton elsewhere /// singleton pattern: define instance field for accessing the singleton elsewhere
/// </summary> /// </summary>
public static AudioManager Instance; public static AudioManager Instance;
/// <summary>
/// function to set don't destroy on load and check for multiple instances
/// </summary>
private void Awake()
{
// check if instance hasn't been set yet
if (Instance == null)
{
// set this instance as the singleton instance
Instance = this;
// don't destroy this instance on scene load
DontDestroyOnLoad(gameObject);
Debug.Log("AudioManager: Awake as singleton instance");
}
// check if instance is already set and it's not this instance
else if (Instance != null && Instance != this)
{
Debug.Log("AudioManager: Awake as non-singleton instance, destroying self");
// destroy the new instance if it's not the singleton instance
Destroy(gameObject);
}
}
// declare separate audio sources for music and sfx // declare separate audio sources for music and sfx
// so we can control their volumes separately // so we can control their volumes separately
[Header("Audio Sources")] [Header("Audio Sources")]
@ -68,7 +44,31 @@ private void Awake()
public AudioClip menuButtonHover; public AudioClip menuButtonHover;
/// <summary> /// <summary>
/// function to set default volumes for the audio sources /// function to set don't destroy on load and check for multiple instances
/// </summary>
private void Awake()
{
// check if instance hasn't been set yet
if (Instance == null)
{
// set this instance as the singleton instance
Instance = this;
// don't destroy this instance on scene load
DontDestroyOnLoad(gameObject);
Debug.Log("AudioManager: Awake as singleton instance");
}
// check if instance is already set and it's not this instance
else if (Instance != null && Instance != this)
{
Debug.Log("AudioManager: Awake as non-singleton instance, destroying self");
// destroy the new instance if it's not the singleton instance
Destroy(gameObject);
}
}
/// <summary>
/// function to set default volumes for the audio sources
/// </summary> /// </summary>
public void Start() public void Start()
{ {
@ -80,7 +80,7 @@ public void Start()
} }
/// <summary> /// <summary>
/// plays the audio clip once on the music source/channel /// plays the audio clip once on the music source/channel
/// </summary> /// </summary>
/// <param name="clip">audio clip to play</param> /// <param name="clip">audio clip to play</param>
public void PlayOnMusicChannel(AudioClip clip) public void PlayOnMusicChannel(AudioClip clip)
@ -89,7 +89,7 @@ public void PlayOnMusicChannel(AudioClip clip)
} }
/// <summary> /// <summary>
/// plays the audio clip once on the sound effects (sfx) source/channel /// plays the audio clip once on the sound effects (sfx) source/channel
/// </summary> /// </summary>
/// <param name="clip">audio clip to play</param> /// <param name="clip">audio clip to play</param>
public void PlayOnSFXChannel(AudioClip clip) public void PlayOnSFXChannel(AudioClip clip)
@ -98,7 +98,7 @@ public void PlayOnSFXChannel(AudioClip clip)
} }
/// <summary> /// <summary>
/// function to get the current volume of the music source/channel /// function to get the current volume of the music source/channel
/// </summary> /// </summary>
/// <returns>volume as float from 0.0 to 1.0</returns> /// <returns>volume as float from 0.0 to 1.0</returns>
public float GetMusicVolume() public float GetMusicVolume()
@ -107,7 +107,7 @@ public float GetMusicVolume()
} }
/// <summary> /// <summary>
/// sets the volume of the music source/channel /// sets the volume of the music source/channel
/// </summary> /// </summary>
/// <param name="volume">float (0.0-1.0) to set the channel volume to</param> /// <param name="volume">float (0.0-1.0) to set the channel volume to</param>
public void SetMusicVolume(float volume) public void SetMusicVolume(float volume)
@ -116,7 +116,7 @@ public void SetMusicVolume(float volume)
} }
/// <summary> /// <summary>
/// function to get the current volume of the sound effects (sfx) source/channel /// function to get the current volume of the sound effects (sfx) source/channel
/// </summary> /// </summary>
/// <returns>volume as float from 0.0 to 1.0</returns> /// <returns>volume as float from 0.0 to 1.0</returns>
public float GetSfxVolume() public float GetSfxVolume()
@ -125,7 +125,7 @@ public float GetSfxVolume()
} }
/// <summary> /// <summary>
/// sets the volume of the sound effects (sfx) source/channel /// sets the volume of the sound effects (sfx) source/channel
/// </summary> /// </summary>
/// <param name="volume">float (0.0-1.0) to set the channel volume to</param> /// <param name="volume">float (0.0-1.0) to set the channel volume to</param>
public void SetSfxVolume(float volume) public void SetSfxVolume(float volume)

View file

@ -6,40 +6,55 @@
using System; using System;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UIElements; using UnityEngine.UIElements;
/// <summary> /// <summary>
/// common menu class for hover and click sound effects /// common menu class for hover and click sound effects
/// on ui toolkit buttons. /// on ui toolkit buttons.
/// override <c>OnEnable()</c> with the first call to <c>base.OnEnable()</c> or <c>PostEnable()</c>, /// override <c>OnEnable()</c> with the first call to <c>base.OnEnable()</c> or <c>PostEnable()</c>,
/// and set the variable <c>GameManager.DisplayState associatedState</c> to the respective menu state /// and set the variable <c>GameManager.DisplayState associatedState</c> to the respective menu state
/// </summary> /// </summary>
public class CommonMenu : MonoBehaviour public class CommonMenu : MonoBehaviour
{ {
/// <summary> /// <summary>
/// associated display state with the menu for the game manager to filter out menus in a scene /// associated display state with the menu for the game manager to filter out menus in a scene
/// </summary> /// </summary>
public GameManager.DisplayState associatedState = GameManager.DisplayState.UnassociatedState; public GameManager.DisplayState associatedState = GameManager.DisplayState.UnassociatedState;
/// <summary> /// <summary>
/// the visual element object for the menu /// manager for audio
/// </summary>
public VisualElement UI;
/// <summary>
/// manager for the game state
/// </summary>
protected GameManager Game;
/// <summary>
/// manager for audio
/// </summary> /// </summary>
protected AudioManager Audio; protected AudioManager Audio;
/// <summary> /// <summary>
/// override this class but call <c>base.OnEnable()</c> first. /// manager for the game state
/// also set the <c>associatedState</c> variable to the respective menu state /// </summary>
protected GameManager Game;
/// <summary>
/// the visual element object for the menu
/// </summary>
public VisualElement UI;
/// <summary>
/// checks if The Menu (2022) was set up correctly
/// </summary>
/// <exception cref="Exception">throws an exception if UI, Game and Audio are not set</exception>
private void Start()
{
if (associatedState == GameManager.DisplayState.UnassociatedState)
throw new Exception("CommonMenu: associatedState not set");
if (Game == null)
throw new Exception("CommonMenu: Game not set (was base.OnEnable() or PostEnable() called?)");
if (Audio == null)
throw new Exception("CommonMenu: Audio not set (was base.OnEnable() or PostEnable() called?)");
}
/// <summary>
/// override this class but call <c>base.OnEnable()</c> first.
/// also set the <c>associatedState</c> variable to the respective menu state
/// </summary> /// </summary>
public virtual void OnEnable() public virtual void OnEnable()
{ {
@ -48,7 +63,7 @@ public virtual void OnEnable()
} }
/// <summary> /// <summary>
/// function to subscribe to mouse events and assign managers /// function to subscribe to mouse events and assign managers
/// </summary> /// </summary>
public void PostEnable() public void PostEnable()
{ {
@ -65,23 +80,7 @@ public void PostEnable()
} }
/// <summary> /// <summary>
/// checks if The Menu (2022) was set up correctly /// function listener for <c>PointerOverEvents</c> and plays a hover sound if it's a button
/// </summary>
/// <exception cref="Exception">throws an exception if UI, Game and Audio are not set</exception>
private void Start()
{
if (associatedState == GameManager.DisplayState.UnassociatedState)
throw new Exception("CommonMenu: associatedState not set");
if (Game == null)
throw new Exception("CommonMenu: Game not set (was base.OnEnable() or PostEnable() called?)");
if (Audio == null)
throw new Exception("CommonMenu: Audio not set (was base.OnEnable() or PostEnable() called?)");
}
/// <summary>
/// function listener for <c>PointerOverEvents</c> and plays a hover sound if it's a button
/// </summary> /// </summary>
/// <param name="evt">event from UIE callback</param> /// <param name="evt">event from UIE callback</param>
public virtual void HoverListener(PointerOverEvent evt) public virtual void HoverListener(PointerOverEvent evt)
@ -93,7 +92,7 @@ public virtual void HoverListener(PointerOverEvent evt)
} }
/// <summary> /// <summary>
/// function listener for <c>ClickEvents</c> and plays a click sound if it's a button /// function listener for <c>ClickEvents</c> and plays a click sound if it's a button
/// </summary> /// </summary>
/// <param name="evt">event from UIE callback</param> /// <param name="evt">event from UIE callback</param>
public virtual void ClickListener(ClickEvent evt) public virtual void ClickListener(ClickEvent evt)
@ -105,7 +104,7 @@ public virtual void ClickListener(ClickEvent evt)
} }
/// <summary> /// <summary>
/// generic decoupled function to play click sound /// generic decoupled function to play click sound
/// </summary> /// </summary>
public virtual void PlayClick() public virtual void PlayClick()
{ {
@ -114,7 +113,7 @@ public virtual void PlayClick()
} }
/// <summary> /// <summary>
/// generic decoupled function to play hover sound /// generic decoupled function to play hover sound
/// </summary> /// </summary>
public virtual void PlayHover() public virtual void PlayHover()
{ {

View file

@ -4,22 +4,21 @@
* description: credits menu script for handling credits menu button functions * description: credits menu script for handling credits menu button functions
*/ */
using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
/// <summary> /// <summary>
/// class managing the credits menu and button function invocations /// class managing the credits menu and button function invocations
/// </summary> /// </summary>
public class CreditsMenu : CommonMenu public class CreditsMenu : CommonMenu
{ {
/// <summary> /// <summary>
/// button to return to main menu /// button to return to main menu
/// </summary> /// </summary>
public Button ButtonReturn; public Button ButtonReturn;
/// <summary> /// <summary>
/// function to associate a display state with the menu, /// function to associate a display state with the menu,
/// and subscribe button events to their respective functions /// and subscribe button events to their respective functions
/// </summary> /// </summary>
public override void OnEnable() public override void OnEnable()
{ {
@ -33,8 +32,8 @@ public override void OnEnable()
} }
/// <summary> /// <summary>
/// handles return to main menu button press, /// handles return to main menu button press,
/// signals the game manager appropriately /// signals the game manager appropriately
/// </summary> /// </summary>
private void OptionReturnToMainMenu() private void OptionReturnToMainMenu()
{ {

View file

@ -4,32 +4,46 @@
* description: game manager singleton for single source of truth state management * description: game manager singleton for single source of truth state management
*/ */
using System;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary> /// <summary>
/// singleton class for managing the game state as a single source of truth /// singleton class for managing the game state as a single source of truth
/// </summary> /// </summary>
public class GameManager : MonoBehaviour public class GameManager : MonoBehaviour
{ {
/// <summary> /// <summary>
/// singleton pattern: define instance field for accessing the singleton elsewhere /// enum for available menus in the game, for use with <c>ShowMenu()</c>
/// </summary>
public enum DisplayState
{
Game,
ScreenMainMenu,
ScreenOptionsMenu,
ScreenCreditsMenu,
ScreenPauseMenu,
ScreenCaughtPause,
ScreenEscapedMenu,
UnassociatedState
}
/// <summary>
/// singleton pattern: define instance field for accessing the singleton elsewhere
/// </summary> /// </summary>
public static GameManager Instance; public static GameManager Instance;
/// <summary> /// <summary>
/// the current state of the game /// the current state of the game
/// </summary> /// </summary>
private DisplayState _state = DisplayState.UnassociatedState; private DisplayState _state = DisplayState.UnassociatedState;
/// <summary> /// <summary>
/// property to check if the game is paused based on the current <c>DisplayState</c> /// property to check if the game is paused based on the current <c>DisplayState</c>
/// </summary> /// </summary>
// TODO: remove this if not needed
public bool Paused => _state != DisplayState.Game; public bool Paused => _state != DisplayState.Game;
/// <summary> /// <summary>
/// function to set don't destroy on load and check for multiple instances /// function to set don't destroy on load and check for multiple instances
/// </summary> /// </summary>
private void Awake() private void Awake()
{ {
@ -54,7 +68,7 @@ private void Awake()
} }
/// <summary> /// <summary>
/// called when game starts, sets state to main menu /// called when game starts, sets state to main menu
/// </summary> /// </summary>
private void Start() private void Start()
{ {
@ -62,40 +76,23 @@ private void Start()
} }
/// <summary> /// <summary>
/// enum for available menus in the game, for use with <c>ShowMenu()</c> /// helper function to hide any menu that is currently showing
/// </summary>
public enum DisplayState
{
Game,
ScreenMainMenu,
ScreenOptionsMenu,
ScreenCreditsMenu,
ScreenPauseMenu,
ScreenCaughtPause,
ScreenEscapedMenu,
UnassociatedState
}
/// <summary>
/// helper function to hide any menu that is currently showing
/// </summary> /// </summary>
private void HideMenuHelper() private void HideMenuHelper()
{ {
// get parent object tagged "Menus" // get parent object tagged "Menus"
foreach (var menu in GameObject.FindGameObjectsWithTag("Menus")) foreach (var menu in GameObject.FindGameObjectsWithTag("Menus"))
// hide each menu under the parent object\
foreach (Transform menuChild in menu.transform)
{ {
// hide each menu under the parent object\ Debug.Log($"GameManager: HideMenuHelper - hiding menu '{menuChild}'");
foreach (Transform menuChild in menu.transform) menuChild.gameObject.SetActive(false);
{
Debug.Log($"GameManager: HideMenuHelper - hiding menu '{menuChild}'");
menuChild.gameObject.SetActive(false);
}
} }
} }
/// <summary> /// <summary>
/// helper function for <c>SetDisplayState()</c> to pause the game, /// helper function for <c>SetDisplayState()</c> to pause the game,
/// called before the incoming game state is set /// called before the incoming game state is set
/// </summary> /// </summary>
/// <param name="incomingState">the to-be-set state of the game</param> /// <param name="incomingState">the to-be-set state of the game</param>
private void PauseGameHelper(DisplayState incomingState) private void PauseGameHelper(DisplayState incomingState)
@ -118,44 +115,50 @@ private void PauseGameHelper(DisplayState incomingState)
return; return;
} }
;
// hide any menu that is currently showing // hide any menu that is currently showing
HideMenuHelper(); HideMenuHelper();
// show the menu based on the incoming state // show the menu based on the incoming state
// 1. get all menus via the parent object tagged "Menus" // 1. get all menus via the parent object tagged "Menus"
foreach (var menuParent in GameObject.FindGameObjectsWithTag("Menus")) foreach (var menuParent in GameObject.FindGameObjectsWithTag("Menus"))
// 2. get all menus under the parent object
foreach (Transform menu in menuParent.transform)
{ {
// 2. get all menus under the parent object // 2. check its associated state
foreach (Transform menu in menuParent.transform) var associatedState = menu.gameObject.GetComponent<CommonMenu>().associatedState;
{ Debug.Log(
// 2. check its associated state $"GameManager: PauseGameHelper - found menu '{menu}' "
var associatedState = menu.gameObject.GetComponent<CommonMenu>().associatedState; + $"with associated state {associatedState} "
Debug.Log( + $"against incoming state {incomingState}");
$"GameManager: PauseGameHelper - found menu '{menu}' with associated state {associatedState} against incoming state {incomingState}");
// 3. if the associated state is the same as the incoming state, then show the menu // 3. if the associated state is the same as the incoming state, then show the menu
if (associatedState != incomingState) if (associatedState != incomingState)
continue; continue;
Debug.Log($"GameManager: PauseGameHelper - showing menu for {incomingState}"); Debug.Log($"GameManager: PauseGameHelper - showing menu for {incomingState}");
menu.gameObject.SetActive(true); menu.gameObject.SetActive(true);
}
} }
} }
/// <summary> /// <summary>
/// helper function for <c>SetDisplayState()</c> to resume the game, /// helper function for <c>SetDisplayState()</c> to resume the game,
/// called before the incoming game state is set /// called before the incoming game state is set
/// </summary> /// </summary>
/// <param name="incomingState">the to-be-set state of the game</param> /// <param name="incomingState">the to-be-set state of the game</param>
private void ResumeGameHelper(DisplayState incomingState) private void ResumeGameHelper(DisplayState incomingState)
{ {
// if we're NOT transitioning from a state of non-gameplay to a state of gameplay, // if we're NOT transitioning from a state of non-gameplay to a state of gameplay,
// (which means currently we are in a state of gameplay),
// then we shouldn't do anything, because the game is already running, // then we shouldn't do anything, because the game is already running,
// so we return early // so we return early
if (_state != DisplayState.Game && incomingState == DisplayState.Game) return; if (_state == DisplayState.Game || incomingState != DisplayState.Game)
{
Debug.Log(
"GameManager: ResumeGameHelper - returning prematurely as" +
$" _state={_state} and incomingState={incomingState}");
return;
}
// else, we should resume the game // else, we should resume the game
Time.timeScale = 1f; Time.timeScale = 1f;
@ -167,8 +170,8 @@ private void ResumeGameHelper(DisplayState incomingState)
} }
/// <summary> /// <summary>
/// function to show a menu based on the enum passed, /// function to show a menu based on the enum passed,
/// and any other necessary actions /// and any other necessary actions
/// </summary> /// </summary>
/// <param name="displayState">the game menu to show</param> /// <param name="displayState">the game menu to show</param>
public void SetDisplayState(DisplayState displayState) public void SetDisplayState(DisplayState displayState)
@ -188,26 +191,26 @@ public void SetDisplayState(DisplayState displayState)
// set the state of the game to the incoming state // set the state of the game to the incoming state
_state = displayState; _state = displayState;
// TODO: post-state change actions case switch // post-state change actions case switch
switch (displayState) switch (displayState)
{ {
// if we're transitioning to the game state, // if we're transitioning to the game state,
// change camera to the player camera // change camera to the player camera
case DisplayState.Game: case DisplayState.Game:
// TODO // TODO: change camera to player camera
return; return;
// if we're transitioning to the main menu state, // if we're transitioning to the main menu state,
// change camera to the main menu camera // change camera to the main menu camera
case DisplayState.ScreenMainMenu: case DisplayState.ScreenMainMenu:
// TODO // TODO: change camera to main menu camera
return; return;
} }
} }
/// <summary> /// <summary>
/// wrapper function to quit the game /// wrapper function to quit the game
/// in case of any cleanup needed /// in case of any cleanup needed
/// </summary> /// </summary>
public void Quit() public void Quit()
{ {
@ -216,10 +219,13 @@ public void Quit()
} }
/// <summary> /// <summary>
/// resets game state and starts a new game, will call <c>SetDisplayState()</c> /// resets game state and starts a new game, will call <c>SetDisplayState()</c>
/// </summary> /// </summary>
public void NewGame() public void NewGame()
{ {
// set to game state
SetDisplayState(DisplayState.Game);
// TODO // TODO
} }
} }

View file

@ -8,33 +8,33 @@
using UnityEngine.UIElements; using UnityEngine.UIElements;
/// <summary> /// <summary>
/// class managing the main menu and button function invocations /// class managing the main menu and button function invocations
/// </summary> /// </summary>
public class MainMenu : CommonMenu public class MainMenu : CommonMenu
{ {
/// <summary> /// <summary>
/// button to play game /// button to show credits menu
/// </summary>
public Button ButtonPlay;
/// <summary>
/// button to show options menu
/// </summary>
public Button ButtonOptions;
/// <summary>
/// button to show credits menu
/// </summary> /// </summary>
public Button ButtonCredits; public Button ButtonCredits;
/// <summary> /// <summary>
/// button to quit game /// button to quit game
/// </summary> /// </summary>
public Button ButtonExit; public Button ButtonExit;
/// <summary> /// <summary>
/// function to associate a display state with the menu, /// button to show options menu
/// and subscribe button events to their respective functions /// </summary>
public Button ButtonOptions;
/// <summary>
/// button to play game
/// </summary>
public Button ButtonPlay;
/// <summary>
/// function to associate a display state with the menu,
/// and subscribe button events to their respective functions
/// </summary> /// </summary>
public override void OnEnable() public override void OnEnable()
{ {
@ -63,18 +63,18 @@ public override void OnEnable()
} }
/// <summary> /// <summary>
/// handles start button press, /// handles start button press,
/// signals the game manager appropriately /// signals the game manager appropriately
/// </summary> /// </summary>
private void OptionStartGame() private void OptionStartGame()
{ {
// start game // start game
Game.SetDisplayState(GameManager.DisplayState.Game); Game.NewGame();
} }
/// <summary> /// <summary>
/// handles credits button press, /// handles credits button press,
/// signals the game manager appropriately /// signals the game manager appropriately
/// </summary> /// </summary>
private void OptionShowCredits() private void OptionShowCredits()
{ {
@ -83,8 +83,8 @@ private void OptionShowCredits()
} }
/// <summary> /// <summary>
/// handles options button press, /// handles options button press,
/// signals the game manager appropriately /// signals the game manager appropriately
/// </summary> /// </summary>
private void OptionShowOptions() private void OptionShowOptions()
{ {
@ -93,8 +93,8 @@ private void OptionShowOptions()
} }
/// <summary> /// <summary>
/// handles quit button press, /// handles quit button press,
/// signals the game manager appropriately /// signals the game manager appropriately
/// </summary> /// </summary>
private void OptionQuitGame() private void OptionQuitGame()
{ {

View file

@ -8,28 +8,28 @@
using UnityEngine.UIElements; using UnityEngine.UIElements;
/// <summary> /// <summary>
/// class managing the credits menu and button function invocations /// class managing the credits menu and button function invocations
/// </summary> /// </summary>
public class OptionsMenu : CommonMenu public class OptionsMenu : CommonMenu
{ {
/// <summary> /// <summary>
/// button to return to main menu /// button to return to main menu
/// </summary> /// </summary>
public Button ButtonReturn; public Button ButtonReturn;
/// <summary> /// <summary>
/// slider for music volume /// slider for music volume
/// </summary> /// </summary>
public Slider SliderAudioMusic; public Slider SliderAudioMusic;
/// <summary> /// <summary>
/// slider for sfx volume /// slider for sfx volume
/// </summary> /// </summary>
public Slider SliderAudioSfx; public Slider SliderAudioSfx;
/// <summary> /// <summary>
/// function to associate a display state with the menu, /// function to associate a display state with the menu,
/// and subscribe button events to their respective functions /// and subscribe button events to their respective functions
/// </summary> /// </summary>
public override void OnEnable() public override void OnEnable()
{ {
@ -58,8 +58,8 @@ public override void OnEnable()
} }
/// <summary> /// <summary>
/// handles return to main menu button press, /// handles return to main menu button press,
/// signals the game manager appropriately /// signals the game manager appropriately
/// </summary> /// </summary>
private void OptionReturnToMainMenu() private void OptionReturnToMainMenu()
{ {
@ -68,8 +68,8 @@ private void OptionReturnToMainMenu()
} }
/// <summary> /// <summary>
/// handle music volume slider change, /// handle music volume slider change,
/// sets the music channel volume in the audio manager appropriately /// sets the music channel volume in the audio manager appropriately
/// </summary> /// </summary>
/// <param name="evt"></param> /// <param name="evt"></param>
private void OptionSetMusicVolume(ChangeEvent<float> evt) private void OptionSetMusicVolume(ChangeEvent<float> evt)
@ -80,8 +80,8 @@ private void OptionSetMusicVolume(ChangeEvent<float> evt)
} }
/// <summary> /// <summary>
/// handle sfx volume slider change, /// handle sfx volume slider change,
/// sets the sfx channel volume in the audio manager appropriately /// sets the sfx channel volume in the audio manager appropriately
/// </summary> /// </summary>
/// <param name="evt"></param> /// <param name="evt"></param>
private void OptionSetSfxVolume(ChangeEvent<float> evt) private void OptionSetSfxVolume(ChangeEvent<float> evt)