csharpunity工具类

[Unity 3d] 60 行代码实现通用模态提示窗口

2022-09-09  本文已影响0人  雨落随风

在本文,笔者将教大家使用 60 行不到的代码实现一个通用的模态提示窗口(modal notification window)

前言:

在软件工程中,提示窗口往往必不可少,越多的提示代表越好的用户体验,那如何用最精悍的代码,实现相对够用的模态提示窗口呢?

如何量化“相对够用”:

演示:

在贴出细节实现前,先看看实际使用效果:

notification

动画中的配套测试代码,是不是很简单?

using UnityEngine;
using static zFramework.UI.NotificationManager;
public class TestNotification : MonoBehaviour
{
    public void ShowMessage() => _ = ShowAsync("这个消息没有按钮,点空白区域关闭"); //也可以使用 await 等待
    public async void ShowAutoMessage()
    {
        _= ShowAsync("这个消息没有按钮、用户不能关闭,空白区域震窗、2 秒后自动关闭", interactable: false);
        await UniTask.Delay(2000); // 也可以是其他判断关闭提示窗的逻辑
        CloseNotification();
    }
    public async void ShowMessageWithConfirm()
    {
        await ShowAsync("带确认按钮的消息,点空白区域关闭会震窗", true);
        Debug.Log($"{nameof(TestNotification)}: 点击了确定按钮!");
    }
    public async void ShowMessageWithCancel()
    {
        await ShowAsync("带取消按钮的消息,点空白区域关闭会震窗", enablecancel: true);
        Debug.Log($"{nameof(TestNotification)}: 点击了取消按钮!");
    }
    public async void ShowMessageWith2Button()
    {
        var index = await ShowAsync("这个消息有 2 个按钮,点空白区域震窗", enableConfirm: true, enablecancel: true);
        Debug.Log($"{nameof(TestNotification)}: 用户点击了{(index == 0 ? "确定" : "取消")}");
    }
}

实现:

先构建一个通知 Notifacation

using DG.Tweening;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(CanvasGroup))]
public class Notification : MonoBehaviour
{
    public TextMeshProUGUI text;
    public Transform window;
    public Button mask_button;
    public Button confirm_button;
    public Button cancel_button;
    public CanvasGroup canvasGroup;
    public void Init(string message, bool enableConfirm, bool enablecancel, bool interactable)
    {
        text.text = message;
        confirm_button.gameObject.SetActive(interactable&&enableConfirm);
        cancel_button.gameObject.SetActive(interactable && enablecancel);
        mask_button.onClick.AddListener(() =>
        {
            if (enablecancel || enableConfirm|| !interactable)
                window.DOShakePosition(0.5f, 5);
            else
                Destroy(gameObject);
        });
        canvasGroup.blocksRaycasts = false;
        window.localScale = Vector3.one * 0.2f;
    }
}

再实现一个通知管理器 NotificationManager

using Cysharp.Threading.Tasks;
using DG.Tweening;
using UnityEngine;
namespace zFramework.UI
{
    public class NotificationManager : MonoBehaviour
    {
        public Notification notificationPrefab;
        static NotificationManager instance;
        static Notification notification;
        void Awake() => instance = this;
        public static void CloseNotification() => Destroy(notification.gameObject);
        public static async UniTask<int> ShowAsync(string message, bool enableConfirm = false, bool enablecancel = false, bool interactable = true)
        {
            notification = Instantiate(instance.notificationPrefab, instance.transform, false);
            notification.Init(message, enableConfirm, enablecancel, interactable);
            await notification.window.DOScale(1, 0.5F);
            notification.canvasGroup.blocksRaycasts = true;
            try
            {
                var cancellation = notification.gameObject.GetCancellationTokenOnDestroy();
                var index = await UniTask.WhenAny(notification.confirm_button.OnClickAsync(cancellation), notification.cancel_button.OnClickAsync(cancellation));
                Destroy(notification.gameObject);
                return index;
            }
            catch (System.Exception)
            {
                return 0;
            }
        }
    }
}

最后 UI 配套

Notification UI搭建
Notification 测试环境搭建

写到最后:

版权所有,转载请注明出处..

上一篇 下一篇

猜你喜欢

热点阅读