Unity,UI之音量控制

今天花3小时写了个简单的音量控制器,还是参考唐老狮的视频…不管怎么说也是写出来了,感觉理论到实践还是挺难的,经常出Bug,于是记录一下思路和踩的坑。

整体思路

打算先写好BaseUI和UIManager两个脚本(另一篇文章有写UI管理器逻辑),然后写好BeginPanel和SetPanel;音乐部分首先写一个GameDataMgr作为游戏数据管理器,写一个MusicData记录初始数据,在场上创建空物体BKMusic挂载AudioSource脚本控制音乐播放,给SetPanel写一个同样名字的脚本。创建一个Main的空物体,挂载Main.cs脚本,Main.cs里调用UIManager的逻辑使BeginPanel刚开始运行时就出现。
大体流程是,运行项目,首先Main.cs调用UIManager.Instance.ShowPanel();我们点击设置按钮、会调出SetPanel,点击SetPanel右上角叉号会隐藏并在场景删除SetPanel;BKMusic向外部提供方法控制身上AudioSource组件的mute和volumn

踩坑记录

1.未能实例化出物体。运行好几次,总告诉我未能实例化出物体,不聪明的我用Debug.Log和try...catch来找Bug,发现这类问题一般有两个。一是资源路径填错,Resources.Load根本找不到文件、那就加载不出来;二是单例模式写错了,我只写了private static T instance;但是我从未给instance赋值O_o,于是出bug。

2.一个等号引发的悲剧我点开设置面板、关闭后就点不开了,于是我去检查我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;

public abstract class BaseUI : MonoBehaviour
{
private CanvasGroup canvasGroup;
//淡入淡出速度
public float alphaSpeed = 5.0f;

private bool isShow = false;

private UnityAction _action = null;

protected virtual void Start()
{
//初始化
Init();
}
private void Awake()
{
canvasGroup = GetComponent<CanvasGroup>();
if (canvasGroup == null )
canvasGroup = this.AddComponent<CanvasGroup>();
}

private void Update()
{
...
if (!isShow && canvasGroup.alpha > 0f)
{
canvasGroup.alpha -= Time.deltaTime * alphaSpeed;
if (canvasGroup.alpha < 0f )
{
canvasGroup.alpha = 0f;
_action?.Invoke();
}
}
}

public void ShowMe()...
public void HideMe(UnityAction action)
{
isShow = false;
_action = action;
}

protected abstract void Init();
}

问题就出在if (canvasGroup.alpha < 0f )这一句代码,因为alpha一般不会小于0,我写的委托_action根本不会调用,而_action这个委托里写的是销毁SetPanel面板,结果就是面板没有销毁,再次点“设置的时候”给你生成面板了,但这个面板是透明的,给人一种点不开的错觉。


3.拖动条数据不保存。音乐数据保存逻辑是这样的,GameDataMgr里专门有一个MusicData类型的变量musicData,我们拖动滑动条、会改变musicData里的数据,这个musicData的数据影响BKMusic的数据。

我在写代码时,发现每次点开游戏音量条都是0,找了半天Bug发现自己没有初始化,以及把滑动条的值传给musicData,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using UnityEngine;
using UnityEngine.UI;

public class SetPanel : BaseUI
{
public Button btnClose;
public Toggle toggleMusic;
public Toggle toggleSound;
public Slider sliderMusic;
public Slider sliderSound;
protected override void Init()
{
//我发现我没初始化
MusicData data = GameDataMgr.Instance.musicData;
toggleMusic.isOn = data.musicOpen;
toggleSound.isOn = data.soundOpen;
sliderMusic.value = data.MusicValue;
sliderSound.value = data.SoundValue;
btnClose.onClick.AddListener(() =>
{
GameDataMgr.Instance.SaveMusicData();
UIManager.Instance.HidePanel<SetPanel>();
//关闭的时候我们再保存数据
});
//音乐开关
toggleMusic.onValueChanged.AddListener((v) =>
{
GameDataMgr.Instance.musicData.musicOpen = v;
BKMusic.Instance.SetIsOpen(v);
});
//音效开关
toggleSound.onValueChanged.AddListener((v) =>
{
GameDataMgr.Instance.musicData.soundOpen = v;
});
//音乐大小
sliderMusic.onValueChanged.AddListener((v) =>
{
//我发现我都没去把v值传给musicData
GameDataMgr.Instance.musicData.MusicValue = v;
BKMusic.Instance.ChangeValue(v);
});
//音效大小
sliderSound.onValueChanged.AddListener((v) =>
{
//音效值
GameDataMgr.Instance.musicData.SoundValue = v;
});
}
}