unity中MVP模式学习

#####该文章是个人学习MVP模式的总结和实践,水平有限,谢谢指点。

 


前言

在游戏开发的过程中,经常会遇到修改界面风格,但是界面的功能没有发生变化的情况。如果界面和逻辑可以分开,那么改动就会减少。MVP模式可以把界面的显示,操作,和数据分离,很适合经常修改的界面。


 

一、MVP模式是什么?

MVP全称为Model,View,Presenter。

Model,模型,用于处理数据;

View,视图,用于显示模型中的数据;

Presenter,展示器,用于处理界面逻辑,View和Model的交互更新等。


它们之间的关系是:

View监听用户输入,发送给Presenter,Presenter根据输入执行Model中对应的数据更新操作,Model中数据变化之后通知Presenter,Presenter收到通知就从Model中获取数据更新View。

和MVC不同的是,MVP中M和V没有联系,所有的逻辑操作都是在Presenter中完成,Presenter可以监听Model的通知然后刷新View。

二、unity中实现

1.整体流程

 

2.具体实现

实现了一个简单的UI,里面显示角色的基本信息。

 

MVP接口

namespace MVP
{
    /*
     *  Model接口 
     */
    public interface IUIModel
    {
        void Init();
    }
}

namespace MVP
{
    /*
     *  view接口
     */
    public interface IUIView
    {
        void PreInit();
    }
}

 

namespace MVP
{
    /*
     * Controller接口
     */
    public interface IUIPresenter
    {
        void PreInit(string path);
        void Show(object data);
        void Hide();
        void Dispose();
    }
}

 界面实现

namespace MVP
{
    public class RoleInfoModel : IUIModel
    {
        public string Name;
        public string Quality;
        public int Hp;
        public int Attack;
        public int Defense;

        public void Init()
        {
            Name = "曹操";
            Quality = "极品";
            Hp = 100;
            Attack = 200;
            Defense = 300;
        }

        public void Upgrade()
        {
            Hp += 100;
            Attack += 20;
            Defense += 20;
            GameEvents.TriggerEvent(eEventType.RoleInfo_OnUpgrade);
        }
    }
}


 

using UnityEngine.UI;
using UnityEngine;
namespace MVP
{

    public class RoleInfoView : MonoBehaviour, IUIView
    {
        [HideInInspector]
        public Text roleName;
        [HideInInspector]
        public Text quality;
        [HideInInspector]
        public Text hp;
        [HideInInspector]
        public Text attack;
        [HideInInspector]
        public Text defense;
        [HideInInspector]
        public Button upgrade;
        [HideInInspector]
        public Button close;
        [HideInInspector]

        public void PreInit()
        {
            roleName = transform.Find("bg/name").GetComponent<Text>();
            quality = transform.Find("bg/qualityDesc/quality").GetComponent<Text>();
            hp = transform.Find("bg/rightInfo/hp").GetComponent<Text>();
            attack = transform.Find("bg/rightInfo/attack").GetComponent<Text>();
            defense = transform.Find("bg/rightInfo/defense").GetComponent<Text>();
            upgrade = transform.Find("bg/upgrade").GetComponent<Button>();
            close = transform.Find("bg/close").GetComponent<Button>();
        }
    }
}
using System;
using System.Collections.Generic;
using UnityEngine;

namespace MVP
{
    public abstract class UIPresenterBase : MonoBehaviour, IUIPresenter
    {
        protected string uiPath;
        protected abstract IUIView View
        {
            get;
        }
        public virtual void PreInit(string path)
        {
            uiPath = path;
        }

        public abstract void Show(object data);
        public abstract void Hide();
        public abstract void Dispose();
        protected abstract void RegistEvents();
        protected abstract void UnRegistEvents();
    }
}

 

using UnityEngine;

namespace MVP
{
    public class RoleInfoPresenter : UIPresenterBase
    {
        protected override IUIView View
        {
            get
            {
                return _view;
            }
        }
        private RoleInfoView _view;

        private RoleInfoModel model;
        public override void PreInit(string path)
        {
            base.PreInit(path);
            _view = this.transform.GetComponent<RoleInfoView>();
            _view.PreInit();
            model = MVPModels.GetModel(path) as RoleInfoModel;
            if (model == null)
            {
                model = new RoleInfoModel();
                model.Init();
                MVPModels.RegistModel(path, model);
            }
            _view.upgrade.onClick.AddListener(OnClickUpgrade);
            _view.close.onClick.AddListener(OnClickClose);

        }


        public override void Show(object data)
        {
            RoleInfoModel model = MVPModels.GetModel(uiPath) as RoleInfoModel;
            _view.roleName.text = model.Name;
            _view.quality.text = model.Quality;
            _view.hp.text = model.Hp.ToString();
            _view.attack.text = model.Attack.ToString();
            _view.defense.text = model.Defense.ToString();
            RegistEvents();
            this.gameObject.SetActive(true);
        }

        public override void Hide()
        {
            this.gameObject.SetActive(false);
            UnRegistEvents();
        }

        public override void Dispose()
        {

        }

        private void OnClickUpgrade()
        {
            upgradeRole();
        }

        private void OnClickClose()
        {
            UIManager.Instance.HideUI(uiPath);
        }

        protected override void RegistEvents()
        {
            GameEvents.AddGameEvent(eEventType.RoleInfo_OnUpgrade, OnUpgraded);
        }

        protected override void UnRegistEvents()
        {
            GameEvents.RemoveGameEvent(eEventType.RoleInfo_OnUpgrade, OnUpgraded);
        }

        private void OnUpgraded()
        {
            RoleInfoModel model = MVPModels.GetModel(uiPath) as RoleInfoModel;
            _view.hp.text = model.Hp.ToString();
            _view.attack.text = model.Attack.ToString();
            _view.defense.text = model.Defense.ToString();
        }

        public void upgradeRole()
        {
            model.Upgrade();
        }
    }
}

using System;
using System.Collections.Generic;

namespace MVP
{
    public class MVPModels
    {
        private static Dictionary<string, IUIModel> uiModels = new Dictionary<string, IUIModel>();

        public static void RegistModel(string type, IUIModel model)
        {
            if (!uiModels.ContainsKey(type))
            {
                uiModels.Add(type, model);
            }
        }

        public static IUIModel GetModel(string type)
        {
            if (uiModels.ContainsKey(type))
            {
                return uiModels[type];
            }
            return null;
        }
    }
}

MVPModels中存放所有界面的Model。 

代码的绑定:

 

GameEvents是事件管理器,可以注册和分发事件。

eEventType是事件Id的枚举。

 


总结

使用MVP模式制作游戏界面可以让显示和数据解耦,代码层次清晰,易于理解,MVP中View层代码因为没有什么逻辑,可以根据UI面板来生成代码,自动绑定。

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值