Unity UI框架(三 消息传递 语言管理器)

Unity目前传递方式比较少,耦合性很高
1.GetComponnet<>方法、字段相互调用
2.SendMessage技术 必须是子节点才能发送
3.单例模式数据传递 中小公司比较多
1.3耦合性强 必须知道是哪个类

开发一种低耦合,无需考虑被传递对象(脚本名称、组件名称)
消息传递中心: 观察者模式 利用委托事件机制

/**
 *Copyright(C) 2019 by DefaultCompany
 *All rights reserved.
 *FileName:     MessageCenter.cs
 *Author:       why
 *Version:      1.0
 *UnityVersion:2018.3.9f1
 *Date:         2019-05-12
 *Description:   消息传递中心
 * 负责UI框架中所有UI窗体之间数据传值
 *History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UIFrameWork
{
    /// <summary>
    /// 键值对 配合委托实现委托传递
    /// </summary>
    public class KeyValuesUpdate
    {
        public string Key { get; }
        public object Values { get; }

        public KeyValuesUpdate(string key, object values)
        {
            Key = key;
            Values = values;
        }
    }

    public class MessageCenter
    {
        public delegate void DelMessageDelivery(KeyValuesUpdate kv);
        /// <summary>
        /// 消息中心缓存合集
        /// </summary>
        public static Dictionary<string, DelMessageDelivery> dicMsgs = new Dictionary<string, DelMessageDelivery>();

        /// <summary>
        /// 添加消息监听
        /// </summary>
        /// <param name="msgType"></param>
        /// <param name="hander"></param>
        public static void AddMsgListener(string msgType, DelMessageDelivery hander)
        {
            if (!dicMsgs.ContainsKey(msgType))
            {
                dicMsgs.Add(msgType, null);
            }
            dicMsgs[msgType] += hander;
        }

        /// <summary>
        /// 取消消息监听
        /// </summary>
        public static void RemoveMsgListener(string msgType, DelMessageDelivery hander)
        {
            if (dicMsgs.ContainsKey(msgType))
            {
                dicMsgs[msgType] -= hander;
            }
        }

        /// <summary>
        /// 取消所有消息监听
        /// </summary>
        public static void RemoveAllMsgListener()
        {
            dicMsgs?.Clear();
        }

        public static void SendMessage(string msgType, KeyValuesUpdate kv)
        {
            if (dicMsgs.TryGetValue(msgType, out DelMessageDelivery del))
            {
                del?.Invoke(kv);
            }
        }
    }

}

BaseUI再封装下

/**
 *Copyright(C) 2019 by DefaultCompany
 *All rights reserved.
 *FileName:     BaseUI.cs
 *Author:       why
 *Version:      1.0
 *UnityVersion:2017.2.2f1
 *Date:         2019-05-10
 *Description:  UI窗体父类
 *定义UI窗体的父类
 * 有四个生命周期
 * 1.Display显示状态
 * 2.Hiding隐藏状态
 * 3.ReDisplay再显示状态
 * 4.Freeze冻结状态 就是弹出窗体后面的窗体冻结
 *History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UIFrameWork
{
    //窗体类型
    public class UIType
    {
        /// <summary>
        /// 是否清空"栈集合" 反向切换
        /// </summary>
        public bool isClearStack = false;
        /// <summary>
        /// UI窗体(位置)类型
        /// </summary>
        public UIFormType type = UIFormType.Normal;
        /// <summary>
        ///UI窗体显示类型
        /// </summary>
        public UIFormShowMode mode = UIFormShowMode.Normal;
        /// <summary>
        /// UI窗体透明度类型
        /// </summary>
        public UIFormLucenyType lucenyType = UIFormLucenyType.Lucency;

    }

    public class BaseUI : MonoBehaviour
    {
        public UIType currentUIType { get; set; } = new UIType();

        #region 窗体的四种状态(生命周期)
        /// <summary>
        /// 显示状态
        /// </summary>
        public virtual void ActiveTrue()
        {
            gameObject.SetActive(true);
            //设置弹出窗体调用
            if (currentUIType.type==UIFormType.PopUp)
            {
                UIMaskMgr.instance.SetMaskWnd(gameObject.transform, currentUIType.lucenyType);
            }
        }
        /// <summary>
        /// 隐藏状态
        /// </summary>
        public virtual void ActiveFalse()
        {
            gameObject.SetActive(false);
            if (currentUIType.type == UIFormType.PopUp)
            {
                UIMaskMgr.instance.CancleMaskWnd();
            }
        }
        /// <summary>
        /// 重新显示状态
        /// </summary>
        public virtual void ReActiveTrue()
        {
            gameObject.SetActive(true);
            if (currentUIType.type == UIFormType.PopUp)
            {
                UIMaskMgr.instance.SetMaskWnd(gameObject.transform, currentUIType.lucenyType);
            }
        }

        /// <summary>
        /// 冻结状态
        /// </summary>
        public virtual void Freeze()
        {
            gameObject.SetActive(true);
        }
        #endregion

        #region 封装子类常用方法
        /// <summary>
        /// 注册按钮事件 
        /// </summary>
        protected void RigisterBtnOnClick(string btnName, EventTriggerListener.VoidDelegate del)
        {
            Transform btn = UnityHelper.Find(gameObject.transform, btnName);
            EventTriggerListener.Get(btn?.gameObject).onClick = del;
        }

        protected void RigisterBtnOnClick(Transform btn, EventTriggerListener.VoidDelegate del)
        {          
            EventTriggerListener.Get(btn?.gameObject).onClick = del;
        }
        /// <summary>
        /// 打开UI窗体
        /// </summary>
        /// <param name="UIName"></param>
        protected void OpenUI(string UIName)
        {
            UIManager.instance.ShowUI(UIName);
        }

        /// <summary>
        /// 关闭UI窗体
        /// </summary>
        protected void CloseUI()
        {
            string UIName;
            //int intPos = -1;
            //命名空间+类名
            UIName = GetType().ToString();
            //查询第一次出现在这在第几位
            //intPos = UIName.IndexOf('.');

            //if (intPos != -1)
            //{
            //    UIName = UIName.Substring(intPos + 1);
            //}

            UIManager.instance.CloseUI(UIName);

        }

        /// <summary>
        /// 发送方法
        /// </summary>
        /// <param name="name">消息类型</param>
        /// <param name="msgName">消息名称</param>
        /// <param name="msgContent">消息内容</param>
        protected void SendMsg(string msgType,string msgName,object msgContent)
        {
            KeyValuesUpdate kv = new KeyValuesUpdate(msgName, msgContent);
            MessageCenter.SendMessage(msgType, kv);
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="msgType"></param>
        /// <param name="hander"></param>
        protected void ReceiveMsg(string msgType,MessageCenter.DelMessageDelivery hander)
        {
            MessageCenter.AddMsgListener(msgType,hander);
        }
        #endregion
    }
}

商店类 发送给之后开的窗口类

/**
 *Copyright(C) 2019 by DefaultCompany
 *All rights reserved.
 *FileName:     ShopUI.cs
 *Author:       why
 *Version:      1.0
 *UnityVersion:2018.3.9f1
 *Date:         2019-05-12
 *Description:   商店UI
 *History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UIFrameWork;
public class ShopUI : BaseUI
{
    private void Awake()
    {
        currentUIType.type = UIFormType.PopUp;
        currentUIType.lucenyType = UIFormLucenyType.ImPenetrable;
        currentUIType.mode = UIFormShowMode.ReverseChange;

        RigisterBtnOnClick("btnClose", go => { CloseUI(); });

        //注册武器
        RigisterBtnOnClick("pink", go => {
            OpenUI(ProConst.PropDataUI);
            SendMsg("Props","pink",new List<string> { });
        });
        RigisterBtnOnClick("purple", go => {
            OpenUI(ProConst.PropDataUI);
            SendMsg("Props", "purple", new string[] { "紫色石头道具详情", "属性" });
        });
        RigisterBtnOnClick("green", go => {
            OpenUI(ProConst.PropDataUI);
            SendMsg("Props", "green", new string[] { "绿色石头道具详情", "属性" });
        });
        RigisterBtnOnClick("blue", go => {
            OpenUI(ProConst.PropDataUI);
            SendMsg("Props", "blue", new string[] { "蓝色石头道具详情", "属性" });
        });
    }
}

/**
 *Copyright(C) 2019 by DefaultCompany
 *All rights reserved.
 *FileName:     PropDataUI.cs
 *Author:       why
 *Version:      1.0
 *UnityVersion:2018.3.9f1
 *Date:         2019-05-12
 *Description:   道具详细信息窗体
 *History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UIFrameWork;
public class PropDataUI : BaseUI
{
    Text nameText;
    private void Awake()
    {

        currentUIType.type = UIFormType.PopUp;
        currentUIType.mode = UIFormShowMode.ReverseChange;
        currentUIType.lucenyType = UIFormLucenyType.Translucence;

        nameText= UnityHelper.Find(gameObject.transform,"Text").GetComponent<Text>();
        ReceiveMsg("Props", hander =>
        {
            if (nameText)
            {
                string[] strArray = hander.Values as string[];
                nameText.text = strArray[0];                
            }
        });

        RigisterBtnOnClick("btnClose", go => CloseUI());
    }
}

就是根据Json加载不同的语言

/**
 *Copyright(C) 2019 by DefaultCompany
 *All rights reserved.
 *FileName:     LauguageMgr.cs
 *Author:       why
 *Version:      1.0
 *UnityVersion:2018.3.9f1
 *Date:         2019-05-12
 *Description:   
 *History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UIFrameWork
{
    public class LauguageMgr : MonoBehaviour
    {
        public static LauguageMgr instance;
        Dictionary<string, string> dicLauguageCache = new Dictionary<string, string>();

        void Awake()
        {
            instance = this;
            Init();
        }

        /// <summary>
        /// 显示文本信息
        /// </summary>
        /// <param name="lauguageID"></param>
        /// <returns></returns>
        public string ShowText(string lauguageID)
        {
            string strQueryResult=string.Empty;
            if (string.IsNullOrEmpty(lauguageID)) return null;
            //查询处理
            if (dicLauguageCache!=null&&dicLauguageCache.Count>=1)
            {
                dicLauguageCache.TryGetValue(lauguageID, out strQueryResult);
                if (!string.IsNullOrEmpty(strQueryResult))
                {
                    return strQueryResult;
                }
            }
            Debug.Log($"{GetType()}/ShowText()/Query is Null! Parameter lauguageID {lauguageID}");
            return null;
        }

        private void Init()
        {
            IConfigManager config = new ConfigManagerByJson("LauguageJSONConfig");
            dicLauguageCache = config?.AppSetting;
        }
    }
}

以Logon为例

/**
 *Copyright(C) 2019 by DefaultCompany
 *All rights reserved.
 *FileName:     LoginUI.cs
 *Author:       why
 *Version:      1.0
 *UnityVersion:2018.3.9f1
 *Date:         2019-05-11
 *Description:   登录窗体
 *History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UIFrameWork;
public class LoginUI : BaseUI
{
    public Text txtLoginName;
    public Text txtLoginNameByBtn;
    void Awake()
    {
        //定义窗口性质 (默认数值)
        currentUIType.type = UIFormType.Normal;
        currentUIType.mode = UIFormShowMode.Normal;
        currentUIType.lucenyType = UIFormLucenyType.Lucency;

        //注册按钮
        RigisterBtnOnClick("btnLogin", go =>
        {
            //前台或者后台检查用户名称与密码

            //如果成功,则登录下一个窗口
            OpenUI(ProConst.SelectUI);
        });
    }

    void Start()
    {
        string str = Show("LogonSystem");
        if (txtLoginName)
        {
            txtLoginName.text = str;
        }
        if (txtLoginNameByBtn)
        {
            txtLoginNameByBtn.text = str;
        }
    }
}

Json表是这样的

{
"ConfigInfo":
[
{"Key":"LogonSystem",
"Value":"LogonSystem"},

{"Key":"Logon",
"Value":"Logon"},

{"Key":"EnterGame",
"Value":"EnterGame"},

{"Key":"MarketSys",
"Value":"MarketSys"},

{"Key":"Return",
"Value":"Return"},

{"Key":"Purchase",
"Value":"Purchase"},

{"Key":"Confirm",
"Value":"OK"},

{"Key":"ConfirmWindow",
"Value":"ConfirmWindow"},

{"Key":"ClozeDetailInfo",
"Value":"ClothDetailInfo:"},

{"Key":"shoeDetailInfo",
"Value":"shoeDetailInfo:"},

{"Key":"Cancle",
"Value":"Cancle"}
]
}

拖到一个空物体上

image.png

记得Logon 界面把Text 拖进来
image.png

然后就一件改变了
image.png

这里是源码地址
https://github.com/1004019267/UIFrameWork/tree/master

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容