您的位置:首页 > 移动开发 > Unity3D

[Unity框架]PureMVC在unity中的简单使用

2017-07-19 11:15 357 查看
http://blog.csdn.net/lyh916/article/details/50076463

效果图:



如上图所示,是一个十分简单的东西,但这次我们要结合PureMVC去实现它。

1.首先,我们知道要使用PureMVC,最主要就是去实现Facade、Proxy、Mediator、SimpleCommand(或MacroCommand)的子类,而这些子类显然是不能挂在物体上的。因为子类没有继承MonoBehaviour,所以常用的Find、GetComponent我们是用不到的,这时候我们就可以把MonoBehaviour的一部分功能封装到一个类里,由这些子类去调用,这样就可以解决问题了。

[csharp]
view plain
copy

print?

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 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;
}
}


2.同时我们也知道PureMVC的通信是通过Notification和观察者模式去实现的,Notification通常用字符串常量去表示,为了方便管理,应该把这些常量放到一个类中。

[csharp]
view plain
copy

print?

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 NotificationConstant {

public const string LevelUp = "LevelUp";
public const string LevelChange = "LevelChange";
}


3.接下来我们对数据进行定义。TestProxy会在数据发生变化时发送通知,进而更新view组件。

<
c23c
strong>[csharp][/b]
view plain
copy

print?

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;

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;
}
}


[csharp]
view plain
copy

print?

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 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);
}

}


4.再接下来我们来实现Mediator的子类,当点击按钮时发送通知。

[csharp]
view plain
copy

print?

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 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;
}

}
}


5.接着就是对业务逻辑的处理。

[csharp]
view plain
copy

print?

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 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);
}
}


6.最后把上面的几个类进行注册,注册的内部包含了对通知的订阅。

[csharp]
view plain
copy

print?

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());  
    }  

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就可以了)

[csharp]
view plain
copy

print?

using UnityEngine;  
using System.Collections;  
  
public class Test : MonoBehaviour {  
  
    void Start ()   
    {  
           new TestFacade(gameObject);  
    }  
}  

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也可以搞得很好。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: