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"}
]
}
拖到一个空物体上
记得Logon 界面把Text 拖进来
然后就一件改变了
这里是源码地址
https://github.com/1004019267/UIFrameWork/tree/master