PureMVC在Unity中的使用(含下载链接)

前言

        Pure MVC是在基于模型、视图和控制器MVC模式建立的一个轻量级的应用框架,这种开源框架是免费的,它最初是执行的ActionScript 3语言使用的Adobe Flex、Flash和AIR,已经移植到几乎所有主要的发展平台,支持两个版本框架:标准和多核,总之,标准版提供了一种简单的编码分离的方法,按照MVC设计概念。

        官方网址:http://puremvc.org/

        下载链接(c#):https://codeload.github.com/PureMVC/puremvc-csharp-standard-framework/zip/refs/heads/master

        官方文档:进入网站后一直下滑,找到China国旗,点击Read PDF既能看到官方的中文PDF文档。

其基本结构为MVC加上常用的设计模式

  • Model(数据模型):关联Proxy(代理)对象,负责处理数据。
  • View(界面):关联Mediator(中介)对象,负责处理界面。
  • Controller(业务控制):管理Command(命令)对象,负责处理业务逻辑。
  • Facade(外观):是MVC三者的经纪人,统管全局,可以获取代理、中介、命令。
  • Notification :通知,负责传递信息。

 导入Unity

Pure MVC导入到Unity中有两种方式:

第一种方法

先打开工程文件

在解决方案处点击生成 

在puremvc-csharp-standard-framework-master\PureMVC\bin\Debug\net5.0这个路径 复制dll文件到Unity的Plugins文件里

第二种方法

在puremvc-csharp-standard-framework-master\PureMVC路径直接复制这三个文件到Unity里

PureMVC思想

Model

        Model在PureMVC中主要负责保存对Proxy对象的引用,并通过这些Proxy对象来操作数据模型,以及与远程服务进行通信以存取数据。Model是MVC架构中的核心部分之一,它负责管理和维护应用程序的数据状态。

Proxy的作用

        Proxy在PureMVC中充当数据模型和应用程序其他部分之间的中介。它提供了一个包装器或中介,使客户端能够方便地访问和操作场景背后的真实对象。Proxy可以管理数据对象(Data Object)以及对数据对象的访问,包括数据的查询、插入、更新和删除等操作。

Obj(Data Objects)类

/// <summary>
/// 玩家数据结构
/// </summary>
public class PlayerDataObj
{//申明一堆玩家属性相关的变量public string playerName;public int lev;public int money;public int gem;public int power;public int hp;public int atk;public int def;public int crit;public int miss;public int luck;
}

Proxy(代理)类

using PureMVC.Patterns.Proxy;
using UnityEngine;/// <summary>
/// 玩家数据代理对象
/// 主要处理 玩家数据更新相关的逻辑
/// </summary>
public class PlayerProxy : Proxy
{//1.继承Proxy父类//2.写构造函数public new const string NAME = "PlayerProxy";public PlayerProxy() : base(PlayerProxy.NAME){//在构造函数中 初始化一个数据 进行关联PlayerDataObj data = new PlayerDataObj();//初始化data.playerName = PlayerPrefs.GetString("PlayerName","玩家01");data.lev = PlayerPrefs.GetInt("PlayerLev", 1);data.money = PlayerPrefs.GetInt("PlayerMoney",9999);data.gem = PlayerPrefs.GetInt("PlayerGem",8888);data.power = PlayerPrefs.GetInt("PlayerPower",99);data.hp = PlayerPrefs.GetInt("PlayerHp", 100);data.atk = PlayerPrefs.GetInt("PlayerAtk", 20);data.def = PlayerPrefs.GetInt("PlayerDef", 10);data.crit = PlayerPrefs.GetInt("PlayerCrit", 20);data.miss = PlayerPrefs.GetInt("PlayerMiss", 10);data.luck = PlayerPrefs.GetInt("PlayerLuck", 40);//赋值给自己的Data进行关联Data = data;}public void LevUp(){PlayerDataObj data = Data as PlayerDataObj;//升级 改变内容data.lev += 1;data.hp += data.lev;data.atk += data.lev;data.def += data.lev;data.crit += data.lev;data.miss += data.lev;data.luck += data.lev;}public void SaveDate(){PlayerDataObj data = Data as PlayerDataObj;//将数据存储到本地PlayerPrefs.SetString("PlayerName",data.playerName);PlayerPrefs.SetInt("PlayerLev",data.lev);PlayerPrefs.SetInt("PlayerMoney",data.money);PlayerPrefs.SetInt("PlayerGem",data.gem);PlayerPrefs.SetInt("PlayerPower",data.power);PlayerPrefs.SetInt("PlayerHp",data.hp);PlayerPrefs.SetInt("PlayerAtk",data.atk);PlayerPrefs.SetInt("PlayerDef",data.def);PlayerPrefs.SetInt("PlayerCrit",data.crit);PlayerPrefs.SetInt("PlayerMiss",data.miss);PlayerPrefs.SetInt("PlayerLuck",data.luck);}}

View

Mediator的作用

        一个Mediator通常关联着多个UI组件,负责它们的创建、更新和销毁等生命周期管理。Mediator可以监听来自UI组件的事件,并将这些事件转发给PureMVC框架中的其他部分(如Command或Proxy),同时也可以接收来自其他部分的通知,并据此更新UI组件。

UI(View Components类)

主面板

using UnityEngine;
using UnityEngine.UI;public class MainView : MonoBehaviour
{//1.寻找控件public Button btnRole;public Button btnSill;public Text txtName;public Text txtLev;public Text txtMoney;public Text txtGem;public Text txtPower;//2.提供面板更新的相关方法给外部public void UpdateInfo(PlayerDataObj data){txtName.text =data.playerName;txtLev.text = "LV." + data.lev;txtMoney.text = data.money.ToString();txtGem.text = data.gem.ToString();txtPower.text = data.power.ToString();}
}

角色面板

using UnityEngine;
using UnityEngine.UI;public class RoleView : MonoBehaviour
{//1.寻找控件public Button btnClose;public Button btnLevUp;public Text txtLev;public Text txtHp;public Text txtAtk;public Text txtDef;public Text txtCrit;public Text txtMiss;public Text txtLuck;//2.提供面板更新的相关方法给外部public void UpdateInfo(PlayerDataObj data){txtLev.text = "Lv."+ data.lev;txtHp.text = data.hp.ToString();txtAtk.text = data.atk.ToString();txtDef.text = data.def.ToString();txtCrit.text = data.crit.ToString();txtMiss.text = data.miss.ToString();txtLuck.text = data.luck.ToString();}
}

Mediator(中介者)类

主面板管理

using PureMVC.Interfaces;
using PureMVC.Patterns.Mediator;public class MainViewMediator : Mediator
{public static new string NAME = "MainViewMediator";//套路写法//1.继承PureMVC中的Meditor脚本//2.写构造函数public MainViewMediator() : base(NAME){//这里写创建界面预设体等等的逻辑//但是界面显示应该是触发的控制的//而且创建界面的代码 重复性比较高}//3.重写监听通知方法public override string[] ListNotificationInterests(){//PureMVC的规则//需要监听哪些通知 就在这里将通知们通过字符串数组的形式返回出去//PureMVC就会帮助我们监听这些通知(类似于通过事件名 注册事件监听)return new string[] {PureNotification.UPDATE_PLAYE_INFO,};}//4.重写处理通知方法public override void HandleNotification(INotification notification){//INotification 对象 里面包含两个对我们来说非常重要的参数//(1).通知名 我们根据这个名字 来做对应的处理//(2).通知包含的信息switch(notification.Name){case PureNotification.UPDATE_PLAYE_INFO://收到 更新通知的时候 做处理if(ViewComponent !=null){(ViewComponent as MainView).UpdateInfo(notification.Body as PlayerDataObj);}break;}}//5.可选:重写注册时的方法public override void OnRegister(){base.OnRegister();//初始化一些内容}public void SetView(MainView view){ViewComponent = view;view.btnRole.onClick.AddListener(() =>{//继承了Mediator,Command,Proxy的类可以直接使用发送通知的方法SendNotification(PureNotification.SHOW_PANEL, "RolePanel");});}
}

角色面板管理

using PureMVC.Interfaces;
using PureMVC.Patterns.Mediator;public class RoleViewMediator : Mediator
{public static new string NAME = "MainViewMediator";//1.继承PureMVC中的Mediator脚本//2.写构造函数public RoleViewMediator() : base(NAME){}//3.重写监听通知的方法public override string[] ListNotificationInterests(){//PureMVC的规则//需要监听哪些通知 就在这里将通知们通过字符串数组的形式返回出去//PureMVC就会帮助我们监听这些通知(类似于通过事件名 注册事件监听)return new string[] {PureNotification.UPDATE_PLAYE_INFO,//关心别的通知 就在这后面通过逗号加起来连接};}//4.重写处理通知的方法public override void HandleNotification(INotification notification){//INotification 对象 里面包含两个对我们来说 重要的参数//1:通知名 根据这个名字来做对应的处理//2.通知包含的信息switch (notification.Name){case PureNotification.UPDATE_PLAYE_INFO://玩家数据更新 逻辑处理if(ViewComponent != null ){(ViewComponent as RoleView).UpdateInfo(notification.Body as PlayerDataObj);}break;}}public void SetView(RoleView view){ViewComponent = view;//关闭按钮事件监听view.btnClose.onClick.AddListener(() =>{//继承了Mediator,Command,Proxy的类可以直接使用发送通知的方法SendNotification(PureNotification.HIDE_PANEL, this);});//升级按钮监听view.btnLevUp.onClick.AddListener(() =>{//升级//通知升级SendNotification(PureNotification.LEV_UP);});}
}

Facade

        Facade为PureMVC中的Model、View和Controller提供了一个统一的访问接口。开发者不需要直接访问这些子系统的具体实现,只需要通过Facade即可。Facade通常被实现为单例模式,以确保整个系统中只有一个Facade实例。

using PureMVC.Patterns.Facade;public class GameFacade : Facade
{//1.继承PureMVC中Facade脚本//2.为了方便我们使用Facade 学要自己写一个单例模式的属性public static GameFacade Instance{get{if(instance==null){instance = new GameFacade();}return instance as GameFacade;}}//3.初始化控制层相关的内容protected override void InitializeController(){base.InitializeController();//这里写一些 关于命令和通知绑定的逻辑//注册初始化命令RegisterCommand(PureNotification.START_UP,()=>{return new StartUpCommand();//当发送START_UP命令时返回一个StartUpCommand()命令并自动执行Excute方法});//注册显示面板命令RegisterCommand(PureNotification.SHOW_PANEL, () =>{return new ShowPanelCommand();});//注册隐藏面板命令RegisterCommand(PureNotification.HIDE_PANEL, () =>{return new HidePanelCommand();});//注册玩家升级命令RegisterCommand(PureNotification.LEV_UP, () =>{return new LevUpCommand();});}//4.启动函数public void StartUp(){//发送通知//(1)第一个参数为想要执行的命令//(2)第二个参数为传入的参数string类型的notification.BodySendNotification(PureNotification.START_UP);//这里是真正开始执行命令的逻辑//SendNotification(PureNotification.SHOW_PANEL,"MainPanel");}
}

Controller

        Controller是PureMVC框架中的消息处理中心,它接收来自View的通知(Notification),并根据通知的类型调用相应的Command来执行特定的业务逻辑。

        在PureMVC中,Command通过注册到Facade上,可以接收来自View或Model的通知。这些通知通常包含了触发事件的相关信息。当Command接收到通知后,它会根据通知的类型和携带的信息,执行相应的业务逻辑。

PureMVC通知类

/// <summary>
/// 这个是pureMVC中的 通知类
/// 主要是用来申明各个通知的 名字
/// 方便使用和管理
/// </summary>
public class PureNotification
{//启动通知public const string START_UP = "startUp";//显示面板通知public const string SHOW_PANEL = "showPanel";//隐藏面板通知public const string HIDE_PANEL = "hidePanel";//代表玩家数据更新的通知名public const string UPDATE_PLAYE_INFO = "updatePlayerInfo";//玩家升级通知public const string LEV_UP = "levUp";
}

初始化命令

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;
public class StartUpCommand : SimpleCommand
{//1.继承Command相关的脚本//2.重写里面的执行函数public override void Execute(INotification notification){base.Execute(notification);//当命令被执行时 就会调用该方法//启动命令中往往是做一些初始化操作//没有这个数据代理 才注册 有了就别注册if(!Facade.HasProxy(PlayerProxy.NAME)){Facade.RegisterProxy(new PlayerProxy());}}
}

显示面板命令

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;
using UnityEngine;
public class ShowPanelCommand : SimpleCommand
{public override void Execute(INotification notification){base.Execute(notification);//写面板创建的逻辑string panelName = notification.Body.ToString();switch(panelName){case "MainPanel"://显示主面板相关内容//如果要使用Mediator 一定也要在Facade中去注册//commend、proxy都是一样的 想要使用 就要注册//可以在命令中直接使用Facade代表的就是唯一的Facadeif(!Facade.HasMediator(MainViewMediator.NAME))//判断Facade里面有没有Mediator,没有就实例化一个,防止Mediator重复{Facade.RegisterMediator(new MainViewMediator());//新建一个Mediator对象,将它传入Facade里面注册}//Facade 得到Mediator的方法MainViewMediator mainMe = Facade.RetrieveMediator(MainViewMediator.NAME) as MainViewMediator;//有了Mediator之后创建界面 预设体if(mainMe.ViewComponent == null){//实例化面板GameObject res = Resources.Load<GameObject>("UI/MainPanel");GameObject obj = GameObject.Instantiate(res);//设置它的父对象 为Canvansobj.transform.SetParent(GameObject.Find("Canvas").transform, false);//得到预设体上的 view脚本 关联到mediator上mainMe.SetView(obj.GetComponent<MainView>());}//实现面板后在这里进行更新//需要把数据通过参数传出去SendNotification(PureNotification.UPDATE_PLAYE_INFO,Facade.RetrieveProxy(PlayerProxy.NAME).Data);break;case "RolePanel"://显示角色面板相关内容if (!Facade.HasMediator(MainViewMediator.NAME)){Facade.RegisterMediator(new MainViewMediator());}RoleViewMediator roleMe = Facade.RetrieveMediator(MainViewMediator.NAME) as RoleViewMediator;if (roleMe.ViewComponent == null){GameObject res = Resources.Load<GameObject>("UI/RolePanel");GameObject obj = GameObject.Instantiate(res);obj.transform.SetParent(GameObject.Find("Canvas").transform, false);roleMe.SetView(obj.GetComponent<RoleView>());}SendNotification(PureNotification.UPDATE_PLAYE_INFO, Facade.RetrieveProxy(PlayerProxy.NAME).Data);break;}}
}

隐藏面板命令

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;
using PureMVC.Patterns.Mediator;
using UnityEngine;public class HidePanelCommand : SimpleCommand
{public override void Execute(INotification notification){base.Execute(notification);//隐藏的目的//得到mediator 在得到mediator 中的 view 然后去要不删除 要不 设置显隐//得到传入的 mediatorMediator m =notification.Body as Mediator;if (m!=null && m.ViewComponent != null){//直接删除场景上的面板对象GameObject.Destroy((m.ViewComponent as MonoBehaviour).gameObject);//删除后置空m.ViewComponent = null;}}
}

升级数据命令

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;public class LevUpCommand : SimpleCommand
{public override void Execute(INotification notification){base.Execute(notification);//得到数据代理 调用升级 升级完成后通知别人 更新数据PlayerProxy playerProxy =Facade.RetrieveProxy(PlayerProxy.NAME) as PlayerProxy;if(playerProxy != null){//升级playerProxy.LevUp();//保存数据//playerProxy.SaveDate();//通知更新SendNotification(PureNotification.UPDATE_PLAYE_INFO,playerProxy.Data);}}
}

总结

        在PureMVC中,通常遵循一种特定的开发流程或“套路”来构建应用程序。这个流程大致可以概括为:先定义Model数据,再设计View界面,然后使用Command命令进行模块间的串联,最后通过Facade类进行模块的判断、注册和获取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/2113.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Python CGI编程-cookie的设置、检索

设置检索 其他&#xff1a; 1. http.cookies和http.cookiejar区别&#xff1a; http.cookies主要用于创建和操作单个cookie对象&#xff0c;适用于需要精细控制单个cookie属性的场景。http.cookiejar则用于管理多个cookie&#xff0c;适用于需要自动处理多个请求和响应中的coo…

算法实现 - 快速排序(Quick Sort) - 理解版

文章目录 算法介绍算法分析核心思想三个版本运行过程挖坑法Hoare 原版前后指针法 算法稳定性和复杂度稳定性时间复杂度平均情况O(nlogn)最差情况O( n 2 n^2 n2) 空间复杂度 算法介绍 快速排序是一种高效的排序算法&#xff0c;由英国计算机科学家C. A. R. Hoare在1960年提出&a…

探索Python新境界:Buzhug库的神秘面纱

文章目录 探索Python新境界&#xff1a;Buzhug库的神秘面纱第一部分&#xff1a;背景介绍第二部分&#xff1a;Buzhug库是什么&#xff1f;第三部分&#xff1a;如何安装Buzhug库&#xff1f;第四部分&#xff1a;Buzhug库函数使用方法第五部分&#xff1a;Buzhug库使用场景第六…

Samtec 技术大咖说 | PCB VS 电缆背板?

【摘要/前言】 选择背板设计需要对特定的网络拓扑结构和应用进行权衡。在某些情况下&#xff0c;对PCB与电缆背板的评估不是 "非此即彼"&#xff0c;而是一种组合方式。 Samtec的工程师Andrew Josephson、Brandon Gore和Jonathan Sprigler进行了一次讨论&#xff0c…

一文解析axios源码

写了几年项目&#xff0c;也用了几年的axios&#xff0c;但是一直也不是很了解其中的原理&#xff0c;为啥他能请求前拦截&#xff0c;也为啥他能响应后拦截&#xff0c;正好有空&#xff0c;所以对他的源码进行分析&#xff0c;从github把他的源码拉下来进行分析: 从package.…

Linux权限问题(账号切换,权限,粘滞位)

1.什么是权限&#xff1f; 在Linux下有两种用户&#xff0c;分别是超级用户&#xff08;root&#xff09;和普通用户。超级用户可以在Linux下做任何事情&#xff0c;几乎不受限制&#xff0c;而普通用户一般只能在自己的工作目录下&#xff08;/home/xxx&#xff09;工作&#…

暴雨高频交易服务器,解决金融行业痛点

随着计算机技术、大数据、人工智能和通信技术的飞速发展&#xff0c;金融市场的交易方式迎来了革命性变化。交易决策和执行过程自动化、智能化&#xff0c;极大提高了交易效率和速度&#xff0c;推动了金融行业的整体创新和发展。 在技术的不断进步和全球金融市场的数字化转型…

三、Kafka集群

一、Kafka集群的概念 1、目的 高并发、高可用、动态扩展。 主备数据架构、双活节点、灾备数据中心。 如果是服务的地理范围过大也可以使不同的集群节点服务不同的区域&#xff0c;降低网络延迟。 2、Kafka集群的基本概念 1&#xff09;复制&#xff08;镜像&#xff09; kaf…

基于 Transformer 的语言模型

基于 Transformer 的语言模型 Transformer 是一类基于注意力机制&#xff08;Attention&#xff09;的模块化构建的神经网络结构。给定一个序列&#xff0c;Transformer 将一定数量的历史状态和当前状态同时输入&#xff0c;然后进行加权相加。对历史状态和当前状态进行“通盘…

大数据之文件服务器方案

大数据文件服务器方案 一&#xff0c;文件服务器常用框架 二&#xff0c;文件服务器常用框架的实现技术 文件服务器常用框架 文件服务器是一种专门用于存储、管理和共享文件的服务器&#xff0c;其常用框架的实现技术涉及多个方面&#xff0c;以下是一些主要的实现技术及其详…

【刷题15】字符串专题

目录 一、字符串相加二、最长公共前缀三、最长回文子串四、二进制求和五、字符串相乘 一、字符串相加 题目&#xff1a; 思路&#xff1a; 字符串中的每一位的字符转换为数字后要相加&#xff0c;相加的必须是同一位的&#xff0c;即个位加个位&#xff0c;十位加十位。所以…

企业数据安全举报投诉如何有效处理?

相关制度、流程图等获取请联系作者&#xff01;&#xff01; 在当今数字化和信息化的浪潮中&#xff0c;企业数据安全问题越来越受到重视&#xff0c;而对于数据安全的举报和投诉处理是保障企业数据安全、提升用户信任度的重要手段之一。一个完善的举报投诉处理机制能够有效应对…

[综述笔记]Deep learning for brain disorder diagnosis based on fMRI images

论文网址&#xff1a;Deep learning for brain disorder diagnosis based on fMRI images - ScienceDirect 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向…

论文提交步骤 | 2024年第五届MathorCup大数据竞赛

2024年第五届MathorCup数学应用挑战赛—大数据竞赛于2024年10月25日下午6点正式开赛。 论文和承诺书、支撑材料&#xff08;可选&#xff09;及计算结果文档由各参赛队队长电脑登录下方报名主页提交&#xff1a; https://www.saikr.com/vse/bigdata2024 初赛作品提交截止时间为…

[sa-token]StpUtil.getLoginId

闲聊 一般情况下&#xff0c;我们想用uid&#xff0c;可能需要前端将uid传过来&#xff0c;或者将token传来&#xff0c;然后我们进行识别。 用了sa-token之后&#xff0c;可以使用StpUtil.getLoginId()方法获取当前会话的用户id 代码展示 例如以下代码&#xff1a; public Res…

双向 Type-C 转 DP 线:高清视频输出的灵活解决方案

在当今数字化生活中&#xff0c;人们对高效能和高清晰度的需求日益增长。双向 Type-C 转 DP 线应运而生&#xff0c;它以其灵活便捷的特点&#xff0c;为用户提供了一种高清视频输出的解决方案。本文将详细介绍双向 Type-C 转 DP 线的技术原理、适用设备、性能参数以及市场选择…

一键式配置适合 Web 开发的Ubuntu系统

大家好&#xff0c;今天给大家分享一个专为Ubuntu设计的Web开发者配置方案Omakub。 项目介绍 Omakub是一个为开发者打造的、经过精心配置的 Ubuntu 环境项目&#xff0c;由 Ruby on Rails 的创造者 David Heinemeier Hansson&#xff08;DHH&#xff09;发起。目的是为了简化他…

使用WebStorm开发Vue3项目

记录一下使用WebStorm开发Vu3项目时的配置 现在WebStorm可以个人免费使用啦&#xff01;&#x1f929; 基本配置 打包工具&#xff1a;Vite 前端框架&#xff1a;ElementPlus 开发语言&#xff1a;Vue3、TypeScript、Sass 代码检查&#xff1a;ESLint、Prettier IDE&#xf…

【OpenGL】vs中glsl高亮显示插件

vs中glsl高亮显示插件 扩展搜索glsl安装

谷歌CEO劈柴吹了个牛,被自家员工“反诈”

Google的CEO Sundar Pichai&#xff0c;可以说是渲染“AI取代人类”的恐慌氛围的帮凶之一了。 谷歌大部分部门都启用了“AI人力”的策略&#xff0c;进行大规模裁员。与一年前相比&#xff0c;现在谷歌的员工整体数量减少了1112人。 甚至&#xff0c;在最新的公司财报电话会议…