zoukankan      html  css  js  c++  java
  • Unity Toast插件(UGUI版)

    简介

    介于自己之前经历的一些开发过程,非常希望unity能有类似Toast的功能用于一些简单的信息显示。但是找来找去找了半天,都木有发现,实在是憋不住了,自己写了个,感觉还可以用,发出来共享一下。。。

    原理

    原理嘛,就是先做一个Toast的prefeb,然后通过一个Manager将Toast生成出来,显示到Canvas。
    然后出于性能考虑,由于反复Instantiate和Destroy对性能消耗巨大,所以内部使用了一个简单的Queue对生成出来的Toast进行了一个缓存。

    使用方法

    将prefeb中的ToastManager拖入到场景中
    这里写图片描述
    像这样
    这里写图片描述
    然后设置prefeb的参数:
    第一个是可以用于显示的Canvas
    第二个是Toast的对象池的大小
    第三个是Toast的prefeb(可以在Res/Prefebs文件夹下找到)
    这里写图片描述
    代码调用方法:
    简单的调用方法,默认的位置和颜色

        public void ShowTopToast(string str)
        {
            LTToastManager.Instance.ShowToast(str);
        }
    

    可以自定义的调用方法,手动设置颜色,显示时间以及位置

        public void ShowBottomToast(string str)
        {
            LTToast tempToast = LTToastManager.Instance.GetToast();
            tempToast.SetColor(Color.green, Color.red);
            tempToast.SetDuring(LTToast.DURING_LONG);
            tempToast.SetText(str);
            tempToast.SetPositionAndSize(LTToast.Position.Bottom);
            tempToast.Show();
        }
    

    实际效果

    这里写图片描述

    代码

    Toast类

    using UnityEngine;
    using UnityEngine.UI;
    
    // 该类与LTToastManager强调用耦合
    // PS:本来是想写成参数传递进入的,但是想了想这两块代码本就是一个模块
    // 能不能算在内聚里面 O(∩_∩)O~
    public class LTToast : MonoBehaviour
    {
    
        public enum Position
        {
            Bottom, Top, Custom
        }
    
        public Image background;
        public Text toastStr;
    
        public const float DURING_LONG = 1f;
        public const float DURING_SHOR = 0.5f;
    
        private const string ENTER_KEY = "enter";
        private const string EXIT_KEY = "exit";
    
        #region Top位置固定参数
        private static Vector2 TopAnchorMin = new Vector2(0, 1);
        private static Vector2 TopAnchorMax = new Vector2(1, 1);
        private static Vector2 TopPivot = new Vector2(0.5f, 1);
        private static Vector3 TopAnchoredPosition3D = new Vector3(0, 0, 0);
        private static Vector2 TopSizeDelta = new Vector3(0, 50);
        #endregion
    
        #region Bottom位置固定参数
        private static Vector2 BottomAnchorMin = new Vector2(0, 0);
        private static Vector2 BottomAnchorMax = new Vector2(1, 0);
        private static Vector2 BottomPivot = new Vector2(0.5f, 0);
        private static Vector3 BottomAnchoredPosition3D = new Vector3(0, 0, 0);
        private static Vector2 BottomSizeDelta = new Vector3(0, 50);
        #endregion
    
        #region 自定义位置参数
        private Vector2 customAnchorMin = new Vector2(0, 0);
        private Vector2 customAnchorMax = new Vector2(1, 0);
        private Vector2 customPivot = new Vector2(0.5f, 0);
        private Vector3 customAnchoredPosition3D = new Vector3(0, 0, 0);
        private Vector2 customSizeDelta = new Vector3(0, 50);
        #endregion
    
        private RectTransform rectTransform;
        private Animator mAnimator;
        private float duringTime = DURING_SHOR;
        private Position showPosition = Position.Top;
        private bool isExit = false;
    
        void Awake()
        {
            rectTransform = this.GetComponent<RectTransform>();
            mAnimator = this.GetComponent<Animator>();
        }
    
        public void SetColor(Color backColor, Color textColor)
        {
            background.color = backColor;
            toastStr.color = textColor;
        }
    
        public void SetDuring(float duringTime)
        {
            this.duringTime = duringTime;
        }
    
        public void SetText(string str)
        {
            toastStr.text = str;
        }
    
        public void SetPositionAndSize(Position showPosition)
        {
            this.showPosition = showPosition;
        }
    
        public void SetPositionAndSize(Vector2 min, Vector2 max, Vector2 pivot, Vector3 anchoredPosition, Vector2 size)
        {
            showPosition = Position.Custom;
            customAnchorMin = min;
            customAnchorMax = max;
            customPivot = pivot;
            customAnchoredPosition3D = anchoredPosition;
            customSizeDelta = size;
        }
    
        private void SetPositionAndSize()
        {
            if (showPosition == Position.Top)
            {
                rectTransform.anchorMin = TopAnchorMin;
                rectTransform.anchorMax = TopAnchorMax;
                rectTransform.pivot = TopPivot;
                rectTransform.anchoredPosition3D = TopAnchoredPosition3D;
                rectTransform.sizeDelta = TopSizeDelta;
            }
            else if (showPosition == Position.Bottom)
            {
                rectTransform.anchorMin = BottomAnchorMin;
                rectTransform.anchorMax = BottomAnchorMax;
                rectTransform.pivot = BottomPivot;
                rectTransform.anchoredPosition3D = BottomAnchoredPosition3D;
                rectTransform.sizeDelta = BottomSizeDelta;
            }
            else if (showPosition == Position.Custom)
            {
                rectTransform.anchorMin = customAnchorMin;
                rectTransform.anchorMax = customAnchorMax;
                rectTransform.pivot = customPivot;
                rectTransform.anchoredPosition3D = customAnchoredPosition3D;
                rectTransform.sizeDelta = customSizeDelta;
            }
            else
            {
                Debug.LogError("检测到未定义位置,采用默认位置");
                rectTransform.anchorMin = TopAnchorMin;
                rectTransform.anchorMax = TopAnchorMax;
                rectTransform.pivot = TopPivot;
                rectTransform.anchoredPosition3D = TopAnchoredPosition3D;
                rectTransform.sizeDelta = TopSizeDelta;
            }
    
        }
    
        public void Show()
        {
            isExit = false;
    
            // 强耦合
            transform.SetParent(LTToastManager.Instance._ShowCanvas.transform);
    
            // 设置位置及缩放的代码建议放在SetParent之后,防止蛋疼
            transform.localScale = Vector3.one;
    
            SetPositionAndSize();
    
            mAnimator.Play(ENTER_KEY);
        }
    
        public void Cancel()
        {
            if (isExit)
            {
                return;
            }
            mAnimator.Play(EXIT_KEY);
            isExit = true;
        }
    
        // UI帧调用,请勿更改
        void EnterDone()
        {
            Invoke("Cancel", duringTime);
        }
    
        // UI帧调用,请勿更改
        void ExitDone()
        {
            // 强耦合
            transform.SetParent(LTToastManager.Instance.transform);
            LTToastManager.Instance.ReturnToast(this);
        }
    
    }
    
    

    ToastManager类

    using UnityEngine;
    using System.Collections.Generic;
    
    public class LTToastManager : MonoBehaviour
    {
    
        private static LTToastManager mInstance;
    
        public static LTToastManager Instance
        {
            get
            {
                return mInstance;
            }
        }
    
        public Canvas _ShowCanvas;
        public int _ToastPoolSize = 5;
        public GameObject _PreToast;
    
        private int currentIndex = 0;
    
        private Queue<LTToast> toastPool;
    
        void Awake()
        {
            mInstance = this;
            toastPool = new Queue<LTToast>();
    
            Init();
        }
    
        private void Init()
        {
            if (null == _ShowCanvas)
            {
                throw new System.Exception("未绑定Canvas");
            }
            if (null == _PreToast)
            {
                throw new System.Exception("未绑定Toast");
            }
    
            // 清除已有的,保持Manager目录清洁(没什么卵用,纯粹洁癖)
            LTGame.LTUtils.ClearChildren(transform);
    
            // 让对象池里面拥有一个Toast对象,提高第一次调用的效率
            ReturnToast(GetToast());
        }
    
        public void ReturnToast(LTToast tempToast)
        {
            if (toastPool.Count < _ToastPoolSize)
            {
                toastPool.Enqueue(tempToast);
            }
            else
            {
                // 如果超出Toast池的最大大小则销毁
                Destroy(tempToast.gameObject);
            }
        }
    
        public LTToast GetToast()
        {
            if (toastPool.Count > 0)
            {
                return toastPool.Dequeue();
            }
            else
            {
                LTToast tempToast = Instantiate(_PreToast).GetComponent<LTToast>();
    
                // 将新生成的对象放置到Manager目录下。
                // PS:其实这段代码不应该放在这里,但是暂时木有找到更好的地方咯~~
                tempToast.transform.SetParent(transform);
    
                return tempToast;
            }
        }
    
        public LTToast ShowToast(string str)
        {
            return ShowToast(str, LTToast.DURING_SHOR);
        }
    
        public LTToast ShowToast(string str, float duringTime)
        {
            return ShowToast(str, Color.black, Color.white, duringTime);
        }
    
        public LTToast ShowToast(string str, Color backColor, Color textColor)
        {
            return ShowToast(str, backColor, textColor, LTToast.DURING_SHOR);
        }
    
        public LTToast ShowToast(string str, Color backColor, Color textColor, float duringTime)
        {
            LTToast result = GetToast();
            result.SetColor(backColor, textColor);
            result.SetText(str);
            result.SetDuring(duringTime);
            result.SetPositionAndSize(LTToast.Position.Top);
            result.Show();
            return result;
        }
    }
    
    

    总结

    也没啥好总结的,先用着吧,哪里不对再改~~~

  • 相关阅读:
    揭秘:如何为 Kubernetes 实现原地升级
    阿里云叔同:以容器为代表的云原生技术,已经成为释放云价值的最短路径
    如何画好一张架构图?(内含知识图谱)
    K8s 资源全汇总 | K8s 大咖带你 31 堂课从零入门 K8s
    15-16年总结——拨开云雾终见青天
    从一个程序员的角度看——微信小应用(第一弹 初学)
    h5直播开发之旅总结
    初探和实现websocket心跳重连(npm: websocket-heartbeat-js)
    组件化h5活动模板的实现
    总结JavaScript事件机制
  • 原文地址:https://www.cnblogs.com/coldcode/p/5128708.html
Copyright © 2011-2022 走看看