我是靠谱客的博主 寒冷丝袜,这篇文章主要介绍【Unity】简易UI框架(带通知弹窗),现在分享给大家,希望可以做个参考。

主要包含:统一控制Panel全屏界面面板及Popup弹窗的显示隐藏,通知消息弹窗,按钮自动添加点击音效

UIManager:统一管理类,统一控制各个界面的显示及隐藏

界面隐藏时,是将界面SetActive(false)了(没有写刷新函数,如果界面已显示,再次调用显示时,最好刷新一次界面),也可以直接Destroy(gameObject)销毁,下次显示时重新创建

在加载创建UI界面时,会给每个Button和Toggle自动添加点击音效(配合音效管理类使用),这里只用了一个通用音效,如果需要多个不同音效,可以给每个界面加一个标记(比如Base类添加一个枚举值,或者界面命名加一个后缀,用name.EndsWith("sign")区分),根据标记绑定对应音效

复制代码
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEngine.UI; using System.Linq; using DG.Tweening; public class UIManager : MonoSingleton<UIManager> { public Camera uiCamera { get; private set; } Transform panelNode; Transform popupNode; Transform barNode; void Awake() { Init(); } void Start() { uiCamera = MainManager.Instance.GetComponentInChildren<Camera>(); ShowPanel<UIStartupPanel>(true); } void Init() { panelNode = transform.Find("PanelRoot"); if (panelNode == null) panelNode = transform; popupNode = transform.Find("PopupRoot"); if (popupNode == null) popupNode = transform; barNode = transform.Find("BarNode"); if (barNode == null) barNode = transform; } #region --- Panel & Popup --- Dictionary<Type, UIBase> uiDic = new Dictionary<Type, UIBase>(); public T LoadUI<T>(params object[] args) where T : UIBase { Type uiType = typeof(T); if (uiDic.ContainsKey(uiType)) { uiDic[uiType].Destroy(); uiDic.Remove(uiType); } T uiPrefab = ResourcesLoader.LoadObject<T>(ConstConfig.uiPrefabPath, uiType.Name); if (uiPrefab == null) return null; T ui = Instantiate(uiPrefab, transform); if (uiPrefab is UIPanelBase) { ui.transform.SetParent(panelNode); } else if (uiPrefab is UIPopupBase) { ui.transform.SetParent(popupNode); } else if (uiPrefab is UIBarBase) { ui.transform.SetParent(barNode); } uiDic.Add(uiType, ui); AddButtonClickSound(ui.transform); ui.Init(args); return ui; } public T GetUI<T>() where T : UIBase { Type uiType = typeof(T); if (!uiDic.ContainsKey(uiType)) LoadUI<T>(); if (uiDic.ContainsKey(uiType)) return uiDic[uiType] as T; return null; } public bool ShowPanel<T>(bool hideOther, params object[] args) where T : UIPanelBase { if (hideOther) HideAllPanel(); //if (showTopBar) // ShowUI<UITopBar>(); //else // HideUI<UITopBar>(); return ShowUI<T>(args); } public bool ShowUI<T>(params object[] args) where T : UIBase { Type uiType = typeof(T); if (!uiDic.ContainsKey(uiType)) LoadUI<T>(); if (uiDic.ContainsKey(uiType)) return ShowUI(uiDic[uiType], args); return false; } public bool ShowUI(UIBase ui, params object[] args) { if (ui == null) return false; ui.Show(args); return true; } public bool ShowNotify(UINotifyInfo notifyInfo) { return ShowUI<UINotifyPopup>(notifyInfo); } public bool ShowNotify(string notifyInfoStr) { return ShowUI<UINotifyPopup>(new UINotifyInfo() { infoStr = notifyInfoStr }); } public bool HideUI<T>(float delayTime = 0) where T : UIBase { Type uiType = typeof(T); if (uiDic.ContainsKey(uiType)) return HideUI(uiDic[uiType], delayTime); return false; } public bool HideUI(UIBase ui, float delayTime) { if (ui == null) return false; if (delayTime > 0) ui.HideDelay(delayTime); else ui.Hide(); return true; } public void HideAllPanel() { var panelDic = uiDic.Where(pair => pair.Value is UIPanelBase); foreach (var item in panelDic) { item.Value.Hide(); } } public void HideAllPopup() { var popupDic = uiDic.Where(pair => pair.Value is UIPopupBase); foreach (var item in popupDic) { item.Value.Hide(); } } public bool DestroyUI<T>() where T : UIBase { Type uiType = typeof(T); if (uiDic.ContainsKey(uiType)) { UIBase toDestroyUI = uiDic[uiType]; uiDic.Remove(uiType); return DestroyUI(toDestroyUI); } return false; } public bool DestroyUI(UIBase ui) { if (ui == null) return false; if (ui.isShow) ui.Hide(); ui.Destroy(); return true; } public void DestroyAllUI() { foreach (var item in uiDic.Values) { item.Destroy(); } uiDic.Clear(); } #endregion #region --- AddButtonClickSound --- public static void GetAllButtonAddListener(Action btnAction) { //获取场景所有物体 Button[] allButtons = Resources.FindObjectsOfTypeAll<Button>(); for (int i = 0; i < allButtons.Length; i++) { allButtons[i].onClick.AddListener(() => btnAction()); } Debug.Log("<color=green>当前场景共有Button组件 : </color>" + allButtons.Length); } public static void AddButtonClickSound(Transform targetObj) { Button[] buttons = targetObj.GetComponentsInChildren<Button>(); for (int i = 0; i < buttons.Length; i++) { int index = i; buttons[index].onClick.AddListener(() => { AudioConteoller.Instance.PlaySoundOnce(ConstConfig.uiBtnClipName); buttons[index].transform.localScale = Vector3.one; buttons[index].transform.DOKill(); buttons[index].transform.DOShakeScale(0.3f, 0.5f); }); } Toggle[] toggles = targetObj.GetComponentsInChildren<Toggle>(); for (int i = 0; i < toggles.Length; i++) { int index = i; toggles[index].onValueChanged.AddListener((b) => { if (b) { AudioConteoller.Instance.PlaySoundOnce(ConstConfig.uiBtnClipName); toggles[index].transform.localScale = Vector3.one; toggles[index].transform.DOKill(); toggles[index].transform.DOShakeScale(0.3f, 0.5f); } }); } } #endregion }

Base基类:所有UI界面都需要继承该类,便于统一管理

可以在基类中定义通用的显示隐藏动画,及其他UI通用函数

复制代码
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
using System.Collections; using System.Collections.Generic; using UnityEngine; public class UIBase : MonoBehaviour { public bool isShow { get { return gameObject.activeSelf; } } public virtual void Init(params object[] args) { //gameObject.SetActive(false); } public virtual void Destroy() { Destroy(gameObject); } public virtual void Show(params object[] args) { if (!gameObject.activeSelf) gameObject.SetActive(true); } public virtual void Hide() { if (gameObject.activeSelf) gameObject.SetActive(false); } public virtual void HideDelay(float delayTime) { if (delayTime <= 0) Hide(); else Invoke("Hide", delayTime); } }

Panel和Popup类

Panel面板:界面中只能同时显示一个Panel,显示下个Panel时需要隐藏当前Panel

Popup弹窗:界面中可以同时显示多个Popup,在显示多个Popup时可以控制子物体顺序,以此改变显示层级顺序

可以在Panel和Popup类中分别定义内部通用函数及显示隐藏动画

复制代码
1
2
3
4
public class UIPanelBase : UIBase { }
复制代码
1
2
3
4
5
public class UIPopupBase : UIBase { }

 MessageNotifer:通知消息管理器

复制代码
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; using System.Linq; //弹窗消息类 public class MessageInfo { public string infoStr { get; private set; } public Color color { get; private set; } //持续显示时间 public float time { get; private set; } public MessageInfo(string messageStr, Color messageColor, float showTime) { infoStr = messageStr; color = messageColor; time = showTime; } } public class MessageNotifer : MonoBehaviour { #region --- Show Message Popup --- [Header("Message Popup")] [SerializeField] UINotifyMessageBar messagePopup; public void ShowMessagePopup(string messageInfoStr) { ShowMessagePopup(new MessageInfo(messageInfoStr, Color.white, 10)); } public void ShowMessagePopup(string messageInfoStr, Color messageInfoColor, float showTime) { ShowMessagePopup(new MessageInfo(messageInfoStr, messageInfoColor, showTime)); } public void ShowMessagePopup(MessageInfo messageInfo) { if (messageInfo == null) return; messagePopup.ShowMessage(messageInfo); } public void ClearMessagePopup() { messagePopup.Clear(); } #endregion #region --- Show Message Bar --- [Header("Message Bar")] //最多显示数量 [SerializeField] int maxShowCount = 5; [SerializeField] Transform messageNode; //消息弹窗预设 [SerializeField] UINotifyMessageBar messageBarPrefab; //待显示消息列表 Queue<MessageInfo> messageInfoQueue = new Queue<MessageInfo>(); //所有可用弹窗列表 List<UINotifyMessageBar> messageBarPool = new List<UINotifyMessageBar>(); // ----------- public void ShowMessageBar(string messageInfoStr) { ShowMessageBar(new MessageInfo(messageInfoStr, Color.black, 1)); } public void ShowMessageBar(string messageInfoStr, Color messageInfoColor, float showTime) { ShowMessageBar(new MessageInfo(messageInfoStr, messageInfoColor, showTime)); } public void ShowMessageBar(MessageInfo messageInfo) { if (messageInfo == null) return; messageInfoQueue.Enqueue(messageInfo); List<UINotifyMessageBar> showMessageBarList = messageBarPool.FindAll(bar => bar.isShow); if (showMessageBarList.Count < maxShowCount) StartCoroutine(ShowMessageInfoBar()); } IEnumerator ShowMessageInfoBar() { if (messageInfoQueue.Count == 0) yield break; MessageInfo toShowInfo = messageInfoQueue.Dequeue(); UINotifyMessageBar messageBar = GetEmptyMessagePopup(); if (messageBar == null) yield break; //设置子物体顺序, 即最新显示的弹窗在最上面 messageBar.transform.SetSiblingIndex(0); yield return StartCoroutine(messageBar.StartShowMessage(toShowInfo)); messageBar.gameObject.SetActive(false); yield return null; if (messageInfoQueue.Count > 0) StartCoroutine(ShowMessageInfoBar()); } // ------ UINotifyMessageBar GetEmptyMessagePopup() { UINotifyMessageBar messageBar = null; messageBar = messageBarPool.FirstOrDefault(bar => !bar.isShow); if (messageBar == null) { messageBar = Instantiate(messageBarPrefab, messageNode); if (messageBar != null) messageBarPool.Add(messageBar); } if (messageBar != null) messageBar.gameObject.SetActive(true); return messageBar; } #endregion }

UINotifyMessageBar:通知消息弹窗,在屏幕指定区域,展示通知消息,不可点击交互,由MessageNotifer统一管理,不在Panel和Popup范围内

复制代码
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; public class UINotifyMessageBar : MonoBehaviour { public bool isShow { get; private set; } CanvasGroup canvasGroup; Text infoText; //淡入/淡出时间 const float fadeTime = 0.5f; void Awake() { canvasGroup = GetComponent<CanvasGroup>(); infoText = GetComponentInChildren<Text>(); Clear(); } public void ShowMessage(MessageInfo messageInfo) { Clear(); StartCoroutine(StartShowMessage(messageInfo)); } public IEnumerator StartShowMessage(MessageInfo messageInfo) { isShow = true; canvasGroup.alpha = 0; infoText.text = messageInfo.infoStr; infoText.color = messageInfo.color; //开始显示 canvasGroup.DOFade(1, fadeTime); //持续一段时间 yield return new WaitForSeconds(fadeTime + messageInfo.time); //开始隐藏 canvasGroup.DOFade(0, fadeTime); yield return new WaitForSeconds(fadeTime); canvasGroup.DOKill(); isShow = false; canvasGroup.alpha = 0; infoText.text = ""; } public void Clear() { StopAllCoroutines(); canvasGroup.DOKill(); isShow = false; canvasGroup.alpha = 0; infoText.text = ""; } }

此外,还可以增加可交互通用弹窗,继承Popup基类:

弹窗显示Title文字说明,有确认和取消两个按钮,每次展示时重新绑定确认/取消按钮事件,方便多个场景通用

实现比较简单,就不贴代码了

最后

以上就是寒冷丝袜最近收集整理的关于【Unity】简易UI框架(带通知弹窗)的全部内容,更多相关【Unity】简易UI框架(带通知弹窗)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(83)

评论列表共有 0 条评论

立即
投稿
返回
顶部