效果图:
如上图所示,是一个十分简单的东西,但这次我们要结合PureMVC去实现它。
1.首先,我们知道要使用PureMVC,最主要就是去实现Facade、Proxy、Mediator、SimpleCommand(或MacroCommand)的子类,而这些子类显然是不能挂在物体上的。因为子类没有继承MonoBehaviour,所以常用的Find、GetComponent我们是用不到的,这时候我们就可以把MonoBehaviour的一部分功能封装到一个类里,由这些子类去调用,这样就可以解决问题了。
using UnityEngine; using System.Collections; public class GameUtility { /// <summary> /// 获取子节点 /// </summary> public static Transform GetChild(GameObject root, string path) { Transform tra = root.transform.Find(path); if (tra == null) Debug.Log(path + "not find"); return tra; } /// <summary> /// 获取子节点组件 /// </summary> public static T GetChildComponent<T>(GameObject root, string path) where T : Component { Transform tra = root.transform.Find(path); if (tra == null) Debug.Log(path + "not find"); T t = tra.GetComponent<T>(); return t; } }
using UnityEngine; using System.Collections; public class NotificationConstant { public const string LevelUp = "LevelUp"; public const string LevelChange = "LevelChange"; }
using UnityEngine; using System.Collections; public class CharacterInfo { public int Level { get; set; } public int Hp { get; set; } public CharacterInfo() { } public CharacterInfo(int level, int hp) { Level = level; Hp = hp; } }
using UnityEngine; using System.Collections; using PureMVC.Patterns; public class TestProxy : Proxy { public new const string NAME = "TestProxy"; public CharacterInfo Data { get; set; } public TestProxy() : base(NAME) { Data = new CharacterInfo(); } public void ChangeLevel(int change) { Data.Level += change; SendNotification(NotificationConstant.LevelChange, Data); } }
using UnityEngine; using System.Collections; using System.Collections.Generic; using PureMVC.Patterns; using UnityEngine.UI; public class TestMediator : Mediator { public new const string NAME = "TestMediator"; private Text levelText; private Button levelUpButton; public TestMediator(GameObject root) : base(NAME) { levelText = GameUtility.GetChildComponent<Text>(root, "Text/LevelText"); levelUpButton = GameUtility.GetChildComponent<Button>(root, "LevelUpButton"); levelUpButton.onClick.AddListener(OnClickLevelUpButton); } private void OnClickLevelUpButton() { SendNotification(NotificationConstant.LevelUp); } public override IList<string> ListNotificationInterests() { IList<string> list = new List<string>(); list.Add(NotificationConstant.LevelChange); return list; } public override void HandleNotification(PureMVC.Interfaces.INotification notification) { switch (notification.Name) { case NotificationConstant.LevelChange : CharacterInfo ci = notification.Body as CharacterInfo; levelText.text = ci.Level.ToString(); break; default : break; } } }
using UnityEngine; using System.Collections; using PureMVC.Patterns; public class TestCommand : SimpleCommand { public new const string NAME = "TestCommand"; public override void Execute(PureMVC.Interfaces.INotification notification) { TestProxy proxy = (TestProxy)Facade.RetrieveProxy(TestProxy.NAME); proxy.ChangeLevel(1); } }
using UnityEngine; using System.Collections; using PureMVC.Patterns; public class TestFacade : Facade { public TestFacade(GameObject canvas) { RegisterCommand(NotificationConstant.LevelUp, typeof(TestCommand)); RegisterMediator(new TestMediator(canvas)); RegisterProxy(new TestProxy()); }
7.最后的最后,对TestFacade进行初始化,并把脚本挂在Canvas上就可以了(其实挂在哪个物体都行,只要ui控件能find就可以了)
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { void Start () { new TestFacade(gameObject); } }
分析:
当点击按钮时,会发送LevelUp的消息,然后TestCommand就会处理这个消息,让等级加一;因为等级的数据发生了变化,所以TestProxy(这个类是对数据的进一步封装)会发送LevelChange的消息,然后TestMediator就会处理这个消息,让UI发生变化。可以看到,TestCommand负责逻辑,TestProxy负责数据,TestMediator负责界面,而TestFacade就是这三个类的总管,结构就很清晰了。
总结:
可以看到,其实对于这样的功能,可以用几行代码就可以实现了,但用PureMVC去实现,却复杂了不少。但是如果要搞一个大工程,MVC的强大就体现出来了。MVC这样的思想应用到unity中应该是不错的,至于要不要使用MVC框架,就见仁见智了,因为有些人不使用PureMVC也可以搞得很好,而有些人使用PureMVC也可以搞得很好。。。