前言:
上篇《unity自制模式(MVC与命令模式相结合)(1)》已经讲述结构的说明已经源码展示,该篇就开始进行UI的实践篇。 直达上一篇(1)
一、准备:
(1)创建文件
(2)将上编文章的代码创建并放置到StaticEventScripts文件夹中
注:该文件夹中的代码不需任何编辑
(3)创建三个动态代码到DynamicEventScripts文件夹中
注:此文件夹中的代码是根据逻辑和面板进行随时编辑的
附上代码:
1.CommandType是动态的,是View发给Handler所发送给Command指定的命令
public enum CommandType
{
DEFAULT,
DemoPanelAddModelCommand,
DemoPanelUpdateModelCommand,
}
2.HandlerUtilities是用于注册Handler的,给Handler一个编号
public class HandlerUtilities
{
public const ushort DemoPanelConfigHandler = 1;
}
3. UIPanelManager是程序的入口,当然你也可以编辑更好的UIPanelManager,我这里只做简单演示(里面的..Panel是下方的View层,如不理解请继续往下阅读)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIPanelManager : MonoBehaviour
{
public static UIPanelManager Instance;
private void Awake()
{
Instance = this;
DemoPanel.InitDemoPanelModel();
}
private void Update()
{
if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.Q))
CommandHandler.Instance.Undo(1);
else if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.R))
CommandHandler.Instance.Redo(1);
}
private DemoPanel demoPanel;
public DemoPanel DemoPanel => demoPanel ??= new DemoPanel();
public DemoPanelConfigArgs currentDemoPanelConfigArgs = new DemoPanelConfigArgs();
}
二、运用:
1.unity创建UI控件 ,然后将UIPanelManager脚本随意挂载游戏对象
2.Model层:DemoPanelConfigArgs
using UnityEngine;
/// <summary>
/// 面板的Model,需绑定相对应的Handler
/// </summary>
public class DemoPanelConfigArgs : AbsUIEventArgs
{
public override ushort HandlerName => DemoPanelConfigHandler.Instance.HandleName;
public CommandType CommandType;
public string inputField1_Text = string.Empty;
public string inputField2_Text = string.Empty;
public string inputField3_Text = string.Empty;
}
3.View层:DemoPanel
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// UI面板初始化
/// </summary>
public class DemoPanel : AbsUIEvent
{
public GameObject demoPanelObj;
private InputField inputField1;
private InputField inputField2;
private InputField inputField3;
public DemoPanel()
{
demoPanelObj = GameObject.Find("Canvas/DemoPanel").gameObject;
inputField1 = demoPanelObj.transform.Find("InputField1").GetComponent<InputField>();
inputField1.onEndEdit.AddListener((text) =>
{
DemoPanelConfigArgs demoPanelConfigArgs = new DemoPanelConfigArgs();
demoPanelConfigArgs.inputField1_Text = text;
demoPanelConfigArgs.inputField2_Text = inputField2.text;
demoPanelConfigArgs.inputField3_Text = inputField3.text;
demoPanelConfigArgs.CommandType = CommandType.DemoPanelUpdateModelCommand;
SendEvent(demoPanelConfigArgs);
});
inputField2 = demoPanelObj.transform.Find("InputField2").GetComponent<InputField>();
inputField2.onEndEdit.AddListener((text) =>
{
DemoPanelConfigArgs demoPanelConfigArgs = new DemoPanelConfigArgs();
demoPanelConfigArgs.inputField1_Text = inputField1.text;
demoPanelConfigArgs.inputField2_Text = text;
demoPanelConfigArgs.inputField3_Text = inputField3.text;
demoPanelConfigArgs.CommandType = CommandType.DemoPanelUpdateModelCommand;
SendEvent(demoPanelConfigArgs);
});
inputField3 = demoPanelObj.transform.Find("InputField3").GetComponent<InputField>();
inputField3.onEndEdit.AddListener((text) =>
{
DemoPanelConfigArgs demoPanelConfigArgs = new DemoPanelConfigArgs();
demoPanelConfigArgs.inputField1_Text = inputField1.text;
demoPanelConfigArgs.inputField2_Text = inputField2.text;
demoPanelConfigArgs.inputField3_Text = text;
demoPanelConfigArgs.CommandType = CommandType.DemoPanelUpdateModelCommand;
SendEvent(demoPanelConfigArgs);
});
}
/// <summary>
/// 初始化面板数据
/// </summary>
public void InitDemoPanelModel()
{
DemoPanelConfigArgs demoPanelConfigArgs = new DemoPanelConfigArgs();
demoPanelConfigArgs.inputField1_Text = "第一个输入框";
demoPanelConfigArgs.inputField2_Text = "第二个输入框";
demoPanelConfigArgs.inputField3_Text = "第三个输入框";
demoPanelConfigArgs.CommandType = CommandType.DemoPanelAddModelCommand;
SendEvent(demoPanelConfigArgs);
}
/// <summary>
/// 操作面板数据
/// </summary>
/// <param name="demoPanelConfigArgs"></param>
public void DemoPanelModelOperate(DemoPanelConfigArgs demoPanelConfigArgs)
{
inputField1.text = demoPanelConfigArgs.inputField1_Text;
inputField2.text = demoPanelConfigArgs.inputField2_Text;
inputField3.text = demoPanelConfigArgs.inputField3_Text;
}
}
3. Control层:DemoPanelConfigHandler
/// <summary>
/// 面板的Handler,将面板要处理的数据转化为命令
/// </summary>
public class DemoPanelConfigHandler : SimpleHandler<DemoPanelConfigHandler>
{
public override ushort HandleName => HandlerUtilities.DemoPanelConfigHandler;
public override void Dispose(IEventArgs args)
{
DemoPanelConfigArgs demoPanelConfigArgs = args as DemoPanelConfigArgs;
DemoPanelCommand demoPanelCommand;
// //命令的处理方式是一样时,可用如下写法
// demoPanelCommand = new DemoPanelCommand(demoPanelConfigArgs);
// CommandHandler.Instance.InsertCommand(demoPanelCommand);
//针对某一命令进行处理
switch (demoPanelConfigArgs.CommandType)
{
case CommandType.DemoPanelAddModelCommand:
demoPanelCommand = new DemoPanelAddModelCommand(demoPanelConfigArgs);
CommandHandler.Instance.InsertCommand(demoPanelCommand);
break;
case CommandType.DemoPanelUpdateModelCommand:
demoPanelCommand = new DemoPanelUpdateModelCommand(demoPanelConfigArgs);
CommandHandler.Instance.InsertCommand(demoPanelCommand);
break;
}
}
}
4.Command层:DemoPanelCommand
public class DemoPanelCommand : AbsCommand
{
private DemoPanelConfigArgs demoPanelConfigArgs;
public DemoPanelCommand() { }
public DemoPanelCommand(DemoPanelConfigArgs currentDemoPanelConfigArgs)
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(currentDemoPanelConfigArgs);
demoPanelConfigArgs = UIPanelManager.Instance.currentDemoPanelConfigArgs;
UIPanelManager.Instance.currentDemoPanelConfigArgs = currentDemoPanelConfigArgs;
}
public override void Execute()
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(demoPanelConfigArgs);
//析构交换
(UIPanelManager.Instance.currentDemoPanelConfigArgs, demoPanelConfigArgs) = (demoPanelConfigArgs, UIPanelManager.Instance.currentDemoPanelConfigArgs);
}
public override void UnExecute()
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(demoPanelConfigArgs);
//析构交换
(UIPanelManager.Instance.currentDemoPanelConfigArgs, demoPanelConfigArgs) = (demoPanelConfigArgs, UIPanelManager.Instance.currentDemoPanelConfigArgs);
}
}
public class DemoPanelAddModelCommand : DemoPanelCommand
{
private DemoPanelConfigArgs demoPanelConfigArgs;
public DemoPanelAddModelCommand(DemoPanelConfigArgs currentDemoPanelConfigArgs)
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(currentDemoPanelConfigArgs);
demoPanelConfigArgs = UIPanelManager.Instance.currentDemoPanelConfigArgs;
UIPanelManager.Instance.currentDemoPanelConfigArgs = currentDemoPanelConfigArgs;
}
public override void Execute()
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(demoPanelConfigArgs);
//析构交换
(UIPanelManager.Instance.currentDemoPanelConfigArgs, demoPanelConfigArgs) = (demoPanelConfigArgs, UIPanelManager.Instance.currentDemoPanelConfigArgs);
}
public override void UnExecute()
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(demoPanelConfigArgs);
//析构交换
(UIPanelManager.Instance.currentDemoPanelConfigArgs, demoPanelConfigArgs) = (demoPanelConfigArgs, UIPanelManager.Instance.currentDemoPanelConfigArgs);
}
}
public class DemoPanelUpdateModelCommand : DemoPanelCommand
{
private DemoPanelConfigArgs demoPanelConfigArgs;
public DemoPanelUpdateModelCommand(DemoPanelConfigArgs currentDemoPanelConfigArgs)
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(currentDemoPanelConfigArgs);
demoPanelConfigArgs = UIPanelManager.Instance.currentDemoPanelConfigArgs;
UIPanelManager.Instance.currentDemoPanelConfigArgs = currentDemoPanelConfigArgs;
}
public override void Execute()
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(demoPanelConfigArgs);
//析构交换
(UIPanelManager.Instance.currentDemoPanelConfigArgs, demoPanelConfigArgs) = (demoPanelConfigArgs, UIPanelManager.Instance.currentDemoPanelConfigArgs);
}
public override void UnExecute()
{
UIPanelManager.Instance.DemoPanel.DemoPanelModelOperate(demoPanelConfigArgs);
//析构交换
(UIPanelManager.Instance.currentDemoPanelConfigArgs, demoPanelConfigArgs) = (demoPanelConfigArgs, UIPanelManager.Instance.currentDemoPanelConfigArgs);
}
}
三、结果演示:
1.运行unity,出现如下:
2.修改输入框数据
此时按下键盘的LeftCtrl+Q可以撤回修改,LeftCtrl+R可以反撤销。
四、小结
此结构,不仅适合UI面板的MVC模式,可以继续实现其他MVC模式,例如IUIEvent结构改成IEvent接口,将AbsUIEvent : IUIEvent继承改至IEvent,同时你还可以继续添加例如AbsSceneEvent : IEvent或者更多的Abs...Event : IEvent,同样也是收发消息的方式去传递Args,让Handler去指定命令去处理数据,去实现更多的MVC模式。如有不清楚的地方可观看上一篇文章 直达上一篇(1)