之前写过一篇我认为的万能应用框架。因为没有经历过项目的考验,所以自己这段时间经常会去思考这个框架的可行性。真的是早晨睡醒的时候会在脑海里跑一边可能遇到以及框架所不能适应的的情况。前几天又有了一些想法,今天就再次添加补充了一些。下面我来说说。
我们之前那片文章说过系统是分为多个管理器来管理各个模块。各个模块通过消息中心进行交互。之前的交互都是无需返回值的信息交互。而如果我们在写剧情游戏的时候,我们需要在游戏控制模块里根据一些参数变化来控制游戏的进度。在游戏控制器里我们可能要在Update函数里一直监测这一游戏阶段的一些参数值从而产生一些游戏响应。所以这里我们需要增加一个带有返回值的函数。
其实,要添加的函数和之前的函数内容差不多,只不过需要添加带有返回值的。因为我们不确定返回值类型,所以我们设定为泛型类型。代码如下:
这是在MessageCenter里的代码:
///
/// 接收到消息后解析发送给对应的模块 有返回值
///
///
public T ReveieveMessage(Message message)
{
BaseManager baseManager=null;
ushort code = message.ID;
baseManager = GetBaseManager(code);
if (baseManager == null)
{
Debug.LogError("无此Manager");return default(T);
}
return baseManager.ReceieveMessage(message);
}
///
/// 接收到消息后解析发送给对应的模块 无返回值
///
///
public void ReveieveMessage(Message message)
{
BaseManager baseManager = null;
ushort code = message.ID;
baseManager = GetBaseManager(code);
if (baseManager == null)
{
Debug.LogError("无此Manager"); return;
}
baseManager.ReceieveMessage(message);
}
同理按照以上方式在其他脚本上分别增加类似带有返回值的同名函数。以下调用仅为在UI模块下的测试,其他模块同理。我们在LoginPanel里调用RegisterPanel里的一个带有返回值和没有返回值的函数。代码如下:
public class LoginPanel : BaseUI
{
//点击注册按钮响应
public void OnRegisterClick()
{
Message message=new Message((ushort)UICode.ShowRegisterPanel);
//无返回值
SendMessage(message);
message = new Message((ushort)UICode.GetRegisterValue);
//有返回值
Debug.Log(SendMessage(message));
}
}
public class RegisterPanel :BaseUI {
void Start()
{
OnInit();
}
public override void OnInit()
{
ushort[] msgIds = new ushort[]
{
(ushort)UICode.ShowRegisterPanel,
(ushort)UICode.HideRegisterPanel
};
RegisterSelf(msgIds, this);
}
public override void OnReceieveMessage(string data)
{
}
public void ShowRegisterPanel()
{
gameObject.SetActive(true);
}
public void HideRegisterPanel()
{
//gameObject.SetActive(false);
Debug.Log("HidePanel");
}
public int GetRegisterValue()
{
return Random.Range(1,8);
}
}
这样我们就可以解决函数体增多的问题。对于跨模块获取值可以在一个函数内执行。当我们有多个场景时,相同的模块我们可以共用,不同的模块我们可以分别设置不同的命名空间来区分对待不同场景的脚本逻辑需求。其实对这个架构,我比较担心的就是反射对项目的效率影响。接下来的项目我会使用本架构进行开发,遇到的问题以后我会补充上来。这是我现在对于自己设计的架构的理解。经验有限,所以肯定会有很多疏忽考虑不到位的地方。希望大家多多指点。
2018.4.17更
今天早晨又是六点多醒了,然后框架又在脑子里跑了一圈。哈哈 有点入迷了 基本有空闲时间就去找一下框架的瑕疵。昨天说的如果反射对项目效率有一个限制,我们可能在Manager里就不用反射的方法,而是使用如下方法,下面以UIManager为例:
///
/// 处理解析code 无返回值
///
///
public override void ReceieveMessage(Message message)
{
BaseUI baseUi;
ushort code = message.ID;
bool IsGet = uiDic.TryGetValue(code, out baseUi);
if (IsGet == false)
{
Debug.LogError("没有此code");
return;
}
baseUi.OnReceieveMessage(message);
}
然后在各个面板进行处理发送过来的消息。如在LoginPanel调用RegisterPanel,代码如下:
private UICode uiCode=UICode.Default;
///
/// 接收消息响应
///
///
public override void OnReceieveMessage(Message message)
{
UICode uiCode = (UICode)(message.ID);
switch (uiCode)
{
case UICode.Default:
Debug.Log("错误");
break;
case UICode.HideRegisterPanel:
HideRegisterPanel();
break;
case UICode.ShowLoginPanel:
ShowRegisterPanel();
break;
}
}
有返回值和无返回值代码都差不多,按照上面更改写个同名函数即可了。
2018.4.19更
昨天下班又想了一下,可以优化的地方。当我们UI模块发消息出去时,如果发送给本模块下的其他脚本,完全没必要发送到消息中心去处理,是浪费资源。所以,我们就可以在UIManager里检测下发送消息的ID是否是在本模块的管理下。代码如下:
///
/// 发送消息给消息中心即 server 无返回值
///
///
public override void SendMesssage(Message message)
{
RegisterUnRegisterPanel(message);
//如果在本模块区间内 直接发送给目标
if (MathHelper.IsBelongThisExtent(message.ID, minValue, maxValue))
{
ReceieveMessage(message);
}//否则发到消息中心去寻找目标
else
{
base.SendMesssage(message);
}
}
public static class MathHelper
{
///
/// 数据是否在这个最小值与最大值的区间内
///
/// 参数
/// 最小值
/// 最大值
///
public static bool IsBelongThisExtent(int id, int min, int max)
{
return id >= min && id < max;
}
}