2016-08-29 15:29:14 wuyt2008 阅读数 4090

Unity是基于组件的,做多了代码难免混乱。因此需要有更好的思路。一个思路就是MVC。但是,在Unity下如何使用MVC的思路来编程,没太多思路。前两天看到一个老外的文章,可以借鉴下。

地址:https://www.toptal.com/unity-unity3d/unity-with-mvc-how-to-level-up-your-game-development

例子下载:http://download.csdn.net/detail/wuyt2008/9615891

下面的图显示了老外的思路


老外设计的结构其实是AMVCC

A是application,用来包含整个项目,并调度用哪个control来响应

M是数据

V是视图,只负责作为事件处理的入口

第一个C是控制器,对所有程序逻辑进行处理

第二个C是组件,不同的组件,组成视图、控制器或模型。




这么说,有点不明白,看下脚本,大概就能理解了。


BounceApplication.cs

using UnityEngine;
using System.Collections;

// 所有类的基类
public class BounceElement : MonoBehaviour
{
	// 让整个应用和所有实例便于访问
	public BounceApplication app { 
		get { 
			return GameObject.FindObjectOfType<BounceApplication> (); 
		}
	}
}
	
public class BounceApplication : MonoBehaviour
{
	// MVC的根实例
	public BounceModel model;
	public BounceView view;
	public BounceController controller;

	//迭代所有控制器和通知数据
	public void Notify (string p_event_path, Object p_target, params object[] p_data)
	{
		BounceController[] controller_list = GetAllControllers ();
		foreach (BounceController c in controller_list) {
			c.OnNotification (p_event_path, p_target, p_data);
		}
	}

	// 获取场景中的所有控制器
	public BounceController[] GetAllControllers ()
	{ 
		BounceController[] arr = { GameObject.FindObjectOfType<BounceController>() };
		return arr;
	}
}

BounceModel.cs

using UnityEngine;

// 包含与应用相关的所有数据
public class BounceModel : BounceElement
{
	// 数据
	public int bounces;	
	public int winCondition;
}


BounceController.cs

using UnityEngine;

// 控制应用的工作流
public class BounceController : BounceElement
{
	// 处理小球碰撞事件
	public void OnNotification(string p_event_path,Object p_target,params object[] p_data)
	{
		switch(p_event_path)
		{
		case BounceNotification.BallHitGround:
			app.model.bounces++;
			Debug.Log("Bounce"+app.model.bounces);
			if(app.model.bounces >= app.model.winCondition)
			{
				app.view.ball.enabled = false;
				app.view.ball.GetComponent<Rigidbody>().isKinematic=true; // 停止小球
				//通知自身或者其他控制器处理事件
				app.Notify(BounceNotification.GameComplete,this);            
			}
			break;

		case BounceNotification.GameComplete:
			Debug.Log("Victory!!");
			break;
		}	
	}
}

BallView.cs

using UnityEngine;

// 小球视图
public class BallView : BounceElement
{

	void OnCollisionEnter() { 
		app.Notify(BounceNotification.BallHitGround,this);
	}
}


BounceView.cs

using UnityEngine;

// 包含与应用相关的所有视图
public class BounceView : BounceElement
{
	public BallView ball;
}

BounceNotification.cs

// 给予事件静态访问的字符串
public class BounceNotification
{
	public const string BallHitGround = "ball.hit.ground";
	public const string GameComplete  = "game.complete";
	/* ...  */
	public const string GameStart     = "game.start";
	public const string SceneLoad     = "scene.load";
	/* ... */
}

如果用这个思路来做,会清晰很多,但是感觉就是程序的耦合度太高了。

2017-06-02 20:02:54 frank901 阅读数 9802

这里写图片描述
这里写图片描述
模型Model脚本(GameModel)

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//model是双向的,中间的
public class GameModel : MonoBehaviour {

    //委托model去通知自身view(是用事件完成的),实例---(通知改变)
    public event UpdateDataEventHandle updateDataEvent;


    //玩家名称
    private string playerName;
    //玩家经验
    private float playerExperience;
    //玩家等级
    private float playerLevel;



    public string PlayerName {
        get {
            return playerName;
        }
        set {
            playerName = value;
            //当值发生改变的时候直接调用更新(通知改变)
            updateDataEvent (playerName, playerExperience, playerLevel);
        }
    }


    public float PlayerExperience {
        get {
            return playerExperience;
        }
        set {
            playerExperience = value;
            updateDataEvent (playerName, playerExperience, playerLevel);
        }
    }


    public float PlayerLevel {
        get {
            return playerLevel;
        }
        set {
            playerLevel = value;
            updateDataEvent (playerName, playerExperience, playerLevel);
        }
    }
}

控制器Controller脚本(GameController)

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//控制器主要是初始化,以及按钮的事件
public class GameController : MonoBehaviour {

    public static GameController instance;

    private GameModel mod;

    private GameView view;

    void Awake(){
        instance = this;
        mod = GetComponent<GameModel> ();//绑定model
        view = GameObject.Find ("Canvas").GetComponent<GameView> ();//绑定View
    }
    void Start(){
        //mod里的委托事件与view绑定(通知改变事件)
        mod.updateDataEvent += view.UpdateViewData;
        ModelInit ();
    }
    void ModelInit(){
    //附上初始值
        mod.PlayerExperience=0;
        mod.PlayerLevel = 1;
        mod.PlayerName="frank901";
    }
    /// <summary>
    /// 按钮事件方法(用户请求)
    /// </summary>
    public void OnButtonClick(){
        //controller通知model(状态改变)
        mod.PlayerExperience += 30;
        if (mod.PlayerExperience >= mod.PlayerLevel * 100) {
            mod.PlayerExperience -= mod.PlayerLevel * 100;
            mod.PlayerLevel++;
        }
    }
}

视图View脚本(GameView)

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
//View主要是UI,监听,中心的显示

public delegate void UpdateDataEventHandle(string name,float experience,float level);//因为是事件(通知改变)所以用到委托

public class GameView : MonoBehaviour {

    private InputField showBox;
    private Button addExBtn;

    void Awake(){
        //找到UI对象
        showBox = transform.Find ("InputField").GetComponent<InputField> ();
        addExBtn = transform.Find ("Button").GetComponent<Button> ();
    }
    //为了防止出现空引用,依据mono生命周期的执行顺序,所以把调用单例放在Start里
    void Start(){
        //绑定GameController的回调(用户请求事件)
        addExBtn.onClick.AddListener(GameController.instance.OnButtonClick);
    }
    //更新数据,通知改变(从model到view)是一个事件(通知改变)
    public void UpdateViewData(string name,float experience,float level){
        showBox.text = "Name:" + name + "Experience:" + experience.ToString() + "level:" + level;
    }
}

这里写图片描述

2016-12-18 17:06:03 qq563129582 阅读数 11456
Unity游戏的开发当中,我并没有刻意地采用MVC框架,因为不像网站开发那样,Model,View,Controller在游戏这个领域里还没有很清晰的定义。
究其原因,可能是由于不同游戏类型本身的软件架构可以相差很远,而且游戏里面的Object之间有大量的交互,所以垂直的MVC似乎不是十分应景。

然而,某种程度的分离代码逻辑是必要的,可以提高代码的可维护性和重用性。
下面我说说自己的一些经验。

假设我们在做一个马里奥:
对于游戏里的角色,我会采用这样一个结构。
Character Manager,它的作用是包含这个角色的Controller(s),并提供一个Dictionary
Controller,利用Reusable Models来处理角色在这个游戏中的某一状态的逻辑。
Reusable Model,是一个虚的概念,并不是一个父类,通常这类Model都负责某一个特定的功能,可以重复利用,可看做游戏引擎的延伸。
我会将Character Manager和Reusable Model继承MonoBehavior,这样我们就能够直观地知道这个角色是什么类型的Character,并且可以利用inspector调节Model的参数。



怎么将上面的架构应用在马里奥身上呢:
作为Character Manager,我们可以采用Finite State Machine或者Behavior Tree。一个好处是它们都天然地提供了“Controller”。
例如Finite State Machine,它的每一个State都可以看作一个Controller。
而Behavior Tree里面的Action Node,也可以看作是一个Controller。

在每一个Controller里面,都会有指针指向一些Reusable Model。
例如下图Move State可以有一个Move Motor,专门来实现GameObject的移动,而Sprite则封装GameObject的表现,如动画、旋转、位置等等。
这些Reusable Model通常都提供丰富的参数可供调整,可以用于不同游戏当中。

用户输入和游戏里面的消息,则会暂存在Character Manager里面的Blackboard里,供Character Manager使用,让它决定是否需要更换Controller。
例如马里奥里面我按左键,往左行动的信息会写在FSM的Blackboard里面,然后通过FSM的State转换机制 [2],从Idle State转换到Move State。
这样的好处是,往左的信息可以从Input Manager (图中没给出)那里得来,也可以从Enemy AI Manager(图中没给出)那里得来。
这样,一个类型(如拥有Idle,Move,Jump等状态)的FSM,就可以用在所有类似的角色身上,无论是玩家控制的还是AI控制的。


最终在Unity里面会是这样一个情况,FSM,Sprite,MoveMotor都作为Component,而Controllers则包含在FSM里面。


以上方案虽然并不严格,但是在一定程度上提高了代码的可复用性和可维护性。
例如现在我基本都把MoveMotor,Sprite等Model写好,新项目就直接扔进来就能用;
MoveState,IdleState,JumpState等一些在平台游戏里常用的状态封装好,留出一些可调参数,例如状态间的转换。

比较原始的FSM会将State转换直接放在State里面,但这样大大降低了State的可复用性。因此可以尝试将State的转换作为一个可调参数。一些可视化的FSM的原理也是这样,利用连线将两个State链接起来,然后通过定义一些转换的条件。




====================================================================================================

Unity是基于组件的,做多了代码难免混乱。因此需要有更好的思路。一个思路就是MVC。但是,在Unity下如何使用MVC的思路来编程,没太多思路。前两天看到一个老外的文章,可以借鉴下。

地址:https://www.toptal.com/unity-Unity3D/unity-with-mvc-how-to-level-up-your-game-development

例子下载:http://download.csdn.NET/detail/wuyt2008/9615891

下面的图显示了老外的思路


老外设计的结构其实是AMVCC

A是application,用来包含整个项目,并调度用哪个control来响应

M是数据

V是视图,只负责作为事件处理的入口

第一个C是控制器,对所有程序逻辑进行处理

第二个C是组件,不同的组件,组成视图、控制器或模型。




这么说,有点不明白,看下脚本,大概就能理解了。


BounceApplication.cs

[csharp] view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. // 所有类的基类  
  5. public class BounceElement : MonoBehaviour  
  6. {  
  7.     // 让整个应用和所有实例便于访问  
  8.     public BounceApplication app {   
  9.         get {   
  10.             return GameObject.FindObjectOfType<BounceApplication> ();   
  11.         }  
  12.     }  
  13. }  
  14.       
  15. public class BounceApplication : MonoBehaviour  
  16. {  
  17.     // MVC的根实例  
  18.     public BounceModel model;  
  19.     public BounceView view;  
  20.     public BounceController controller;  
  21.   
  22.     //迭代所有控制器和通知数据  
  23.     public void Notify (string p_event_path, Object p_target, params object[] p_data)  
  24.     {  
  25.         BounceController[] controller_list = GetAllControllers ();  
  26.         foreach (BounceController c in controller_list) {  
  27.             c.OnNotification (p_event_path, p_target, p_data);  
  28.         }  
  29.     }  
  30.   
  31.     // 获取场景中的所有控制器  
  32.     public BounceController[] GetAllControllers ()  
  33.     {   
  34.         BounceController[] arr = { GameObject.FindObjectOfType<BounceController>() };  
  35.         return arr;  
  36.     }  
  37. }  

BounceModel.cs

[csharp] view plain copy
  1. using UnityEngine;  
  2.   
  3. // 包含与应用相关的所有数据  
  4. public class BounceModel : BounceElement  
  5. {  
  6.     // 数据  
  7.     public int bounces;   
  8.     public int winCondition;  
  9. }  


BounceController.cs

[csharp] view plain copy
  1. using UnityEngine;  
  2.   
  3. // 控制应用的工作流  
  4. public class BounceController : BounceElement  
  5. {  
  6.     // 处理小球碰撞事件  
  7.     public void OnNotification(string p_event_path,Object p_target,params object[] p_data)  
  8.     {  
  9.         switch(p_event_path)  
  10.         {  
  11.         case BounceNotification.BallHitGround:  
  12.             app.model.bounces++;  
  13.             Debug.Log("Bounce"+app.model.bounces);  
  14.             if(app.model.bounces >= app.model.winCondition)  
  15.             {  
  16.                 app.view.ball.enabled = false;  
  17.                 app.view.ball.GetComponent<Rigidbody>().isKinematic=true// 停止小球  
  18.                 //通知自身或者其他控制器处理事件  
  19.                 app.Notify(BounceNotification.GameComplete,this);              
  20.             }  
  21.             break;  
  22.   
  23.         case BounceNotification.GameComplete:  
  24.             Debug.Log("Victory!!");  
  25.             break;  
  26.         }     
  27.     }  
  28. }  

BallView.cs

[csharp] view plain copy
  1. using UnityEngine;  
  2.   
  3. // 小球视图  
  4. public class BallView : BounceElement  
  5. {  
  6.   
  7.     void OnCollisionEnter() {   
  8.         app.Notify(BounceNotification.BallHitGround,this);  
  9.     }  
  10. }  


BounceView.cs

[csharp] view plain copy
  1. using UnityEngine;  
  2.   
  3. // 包含与应用相关的所有视图  
  4. public class BounceView : BounceElement  
  5. {  
  6.     public BallView ball;  
  7. }  

BounceNotification.cs

[csharp] view plain copy
  1. // 给予事件静态访问的字符串  
  2. public class BounceNotification  
  3. {  
  4.     public const string BallHitGround = "ball.hit.ground";  
  5.     public const string GameComplete  = "game.complete";  
  6.     /* ...  */  
  7.     public const string GameStart     = "game.start";  
  8.     public const string SceneLoad     = "scene.load";  
  9.     /* ... */  
  10. }  

如果用这个思路来做,会清晰很多,但是感觉就是程序的耦合度太高了。

======================================================================================
浅谈unity3d中使用MVC框架模式

MVC框架模式,相信很多人都不会陌生,数据-控制-显示分离的工作方式或者叫做代码结构会使软件(游戏)的结构清晰化,逻辑更明了。但由于MVC框架模式各部件都可以与彼此进行沟通,造成了很多新人在使用MVC的时候消息满天飞,解耦没成,耦合度更高了。我建议在使用MVC的时候,制定策略,让消息单向化,不要双向或形成网状。

好了,我们下面讨论一下Unity3D是否可以使用MVC,如何使用会比较好?(方法有很多种,这里我只写我比较认同的一种)
既然我写了有我比较认同的方式,那么在Unity3D中使用MVC至少我个人持赞成态度,任何东西没有好与坏,只有适用不适用。

Unity3D本身的MonoBehavior脚本是一个重大突破,达到了组件式开发的目的。但是我依然要说,东西虽好,不能乱搞。我个人认为:组件式开发是好的方式,但组件本身却是依靠传统的编程方式建立的,所以除开组件最适用的地方外,强制使用组件进行开发是违和的。MonoBehavior脚本,我们可以将它理解为界面层与界面直接沟通的上层脚本,在他底部的控制、逻辑、数据等有必要用MonoBehavior脚本么?至少我认为是不必要的(为什么要用用不到的东西管理数据和逻辑呢?)。底部的控制、逻辑用什么实现好呢?方式很多,至少MVC框架模式是一个选择。而在使用MVC时,我个人认为模块内小规模使用MVC更合理,模块内的数据、控制、界面关系比较紧密,模块之间提供合理的接口进行跳转即可(不排除模块间消息沟通)。而模块内使用MVC时,也要遵循消息流向单向化,即:接收方永不发送消息,发送方永不接收消息。有人说不太可能,我给大家提供一个模型供参考:

1.      定义M只提供两种函数接口:操作、获取数据;并可以发送更新消息
2.      定义V只接收消息并控制界面显示、跳转、效果等
注:界面(暂且称之为UI)自身处理界面点击等操作直接调用M层进行处理或内部消化或发送给V进行控制跳转
3.      定义C实现必要逻辑(非界面自身逻辑)
我们来看以上模型:
a. 用户点击->UI响应控制->调用M更改数据->发送更新界面消息->V接收消息->更新界面
b. 用户点击->UI响应控制->发送界面跳转消息->V接收消息->更新界面
c. 用户点击->UI响应控制->UI自消化
其实,一般的界面模块,用以上的模型就足够了。但有些模块比较复杂,需要不断的与数据和界面交互,这时候C才有意义。
以上方式,纯属个人比较认可的方式,在实际开发中,每个人都会有自己的观点存在,但一个项目只能用统一的方式才方便沟通、交接、扩展…



2018-11-06 16:48:05 q764424567 阅读数 3120

一、前言

MVC是一种比较常见的设计框架,是一种将代码的功能进行划分的一种设计框架,主要原理就是将软件用户界面和业务逻辑分离,以使代码可扩展性、可复用性、可维护性、灵活性加强。
MVC在桌面应用程序,以及网页架构上面用的比较多,那么怎么应用到Unity3d中呢,下面就带大家去了解这个设计框架,以及如何在Unity中应用。

二、MVC介绍

简介

MVC全名是Model View Controller,是模型(Model)-视图(View)-控制器(Controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

Model(模型) 是应用程序中用于处理应用程序数据逻辑的部分。
  通常模型对象负责在数据库中存取数据。
View(视图) 是应用程序中处理数据显示的部分。
  通常视图是依据模型数据创建的。
Controller(控制器) 是应用程序中处理用户交互的部分。
  通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
  
MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

模型-视图-控制器(MVC)是Xerox PARC在二十世纪八十年代为编程语言Smalltalk-80发明的一种软件设计模式,已被广泛使用。后来被推荐为Oracle旗下Sun公司Java EE平台的设计模式,并且受到越来越多的使用ColdFusion和PHP的开发者的欢迎。模型-视图-控制器模式是一个有用的工具箱,它有很多好处,但也有一些缺点。

MVC的业务流程

在这里插入图片描述

MVC是设计模式吗

MVC是一种设计模式,但是却不在Gof总结过的23种设计模式中,所以确切说MVC不是一个设计模式,而是多种设计模式的组合,而不仅仅只是一个设计模式。
组成MVC的三个模式分别是组合模式、策咯模式、观察者模式,MVC在软件开发中发挥的威力,最终离不开这三个模式的默契配合。 那些崇尚设计模式无用论的程序员,请了解只要你们使用MVC,就离不开设计模式。
组合模式只在视图层活动, 视图层的实现用的就是组合模式,当然,这里指的实现是底层的实现,是由编程框架厂商做的事情,用不着普通程序员插手。

组合模式的类层次结构是树状的, 而我们做Web时视图层是html页面,html的结构不正是树状的吗,这其实就是一个组合模式的应用,只是浏览器厂商已经把界面相关的工作帮我们做掉了,但它确确实实是我们应用MVC的其中一部分,只是我们感觉不到罢了,这也是我们觉得View是实现起来最简单最没有歧义的一层的原因。

除网页以外的其他用户界面程序,如WPF、Android、ASP.NET等等都是使用树状结构来组织界面控件对象的,因为组合模式就是从界面设计的通用解决方案总提炼出来的。所以与其说MVC选择了组合模式,还不如说组合模式是必定会存在MVC中的,因为只要涉及到用户界面,组合模式就必定存。事实上即使不理解组合模式,也不影响程序员正确的使用MVC,组合模式本就存在于程序员接触不到的位置。

然而,观察者模式和策略模式就显得比较重要,是实实在在MVC中接触的到的部分。

观察者模式有两部分组成,被观察的对象和观察者,观察者也被称为监听者。对应到MVC中,Model是被观察的对象,View是观察者,Model层一旦发生变化,View层即被通知更新。View层和Model层互相之间是持有引用的。 我们在开发Web MVC程序时,因为视图层的html和Model层的业务逻辑之间隔了一个http,所以不能显示的进行关联,但是他们观察者和收听者的关系却没有改变。当View通过http提交数据给服务器,服务器上的Model接受到数据执行某些操作,再通过http响应将结果回送给View,View(浏览器)接受到数据更新界面,这不正是一个接受到通知并执行更新的行为吗,是观察者模式的另一种表现形式。

但是,脱离Web,当通过代码去纯粹的表示一个MVC结构的时候,View和Model间无疑是观察者和被观察的关系,是以观察者模式为理论基础的。即使在Web中因为http壁垒的原因导致真正的实现有点走样,但是原理核心和思路哲学却是不变的。

最后是策略模式。策略模式是View和Controller之间的关系,Controller是View的一个策略,Controller对于View是可替换的, View和Controller的关系是一对多,在实际的开发场景中,也经常会碰到一个View被多个Controller引用,这即使策咯模式的一种体现,只是不那么直观而已。

总结一下,关于MVC各层之间关系所对应的设计模式

View层,单独实现了组合模式

Model层和View层,实现了观察者模式

View层和Controller层,实现了策咯模式

MVC就是将这三个设计模式在一起用了,将这三个设计模式弄明白,MVC将毫无神秘感可言。如果不了解这三个设计模式去学习MVC,那不管怎么学总归是一知半解,用的时候也难免不会出想问题。

三、参考文章

深入理解MVC https://blog.csdn.net/zuiyingong6567/article/details/80150834
MVC简介 https://www.cnblogs.com/diyunfei/p/6752618.html
【Unity】MVC框架 https://blog.csdn.net/qq_39574690/article/details/80757261
Unity中MVC简单应用 https://www.jianshu.com/p/acc689be52f9
【Unity3D】手游开发实践《腾讯桌球》客户端开发经验总结 https://blog.csdn.net/q764424567/article/details/81020381
MVC框架 https://baike.baidu.com/item/MVC框架/9241230?fr=aladdin&fromid=85990&fromtitle=MVC

四、Unity中使用MVC

在这里插入图片描述
本篇文章主要是讲一下我是如何在Unity中使用MVC模式,MVC模式肯定不能照搬进Unity中,所以很多东西都做了修改,以适合我的项目使用,如果有不对的地方,希望大家能指正出来。

使用原理

在这里插入图片描述
代码文档结构就是这样的
目前我了解的MVC应用到Unity中只有两种模式,一种就是先按照业务功能划分,再按照MVC划分
在这里插入图片描述
蛋糕心语游戏就是这种模式,使得模块更聚焦(高内聚)
第二种就是先按照MVC划分,然后再分出来业务功能
在这里插入图片描述
第二种方式用多了发现随着项目的运营模块增多,没有第一种那么好维护。

MVC的关键就在于业务划分,代码分离,其实跟三层架构比较相似,把业务层、逻辑层、数据层分开来,互相通过一个接口进行调用,但是并不知道接口是怎么实现的。

所以现在的问题就在于如何去划分呢。

实现:
Model(模型层):
在这一层主要就是存放用户的数据,UI的数据,静态字段,数据存储,以及模型贴图资源的存储
比如说:

  • 存放静态字段
    在这里插入图片描述
  • 存放数据
    在这里插入图片描述
  • 存放模型材质字段
    在这里插入图片描述
  • 数据库增删改查操作
    在这里插入图片描述

View(视图层)
在这一层主要是放一些UI参数,获取UI数据,获取按钮事件等
在这里插入图片描述
在这里插入图片描述
点击事件
在这里插入图片描述

Controller(控制层)
这一层就是去实现业务逻辑功能,获取Model的数据,通知View层更新数据,承上启下的功能
在这里插入图片描述

五、实例

就带大家实现在Untiy中使用MVC模式,实现更换图片的功能
步骤一:设计界面
在这里插入图片描述
在这里插入图片描述
步骤二:MVC搭建
Model_Main.cs
在这里插入图片描述
View_Main.cs
在这里插入图片描述
Controller_Main.cs
在这里插入图片描述
在这里插入图片描述

关于那个鼠标点击事件那个方法,在我另一篇文章中有讲到,不懂的可以去那篇帖子仔细看一下。
https://blog.csdn.net/q764424567/article/details/82424308
效果:
在这里插入图片描述
源代码已经上传到CSDN,按需下载
https://download.csdn.net/download/q764424567/10768387

六、总结

PS:程序员最重要的就是总结,不然学的再多到关键时刻用不上还是白搭,总结梳理,然后写下来,当快忘了的时候可以回来看看,会有不一样的体悟哦。
在Unity中应用MVC模式已经讲解完了,MVC模式其实就是多种设计模式的结合体,也是三层架构的改良产品,基本原理就是把业务逻辑、功能实现、数据给分开来,利于增加功能,和维护。
俗话说的好,一千个人就有一千个哈姆雷特,每个人研究MVC之后,运用到Unity中的方法都不尽相同,方法也是很多样,我主要就是提供一个想法和思路,更多优化运用还要大家多开动脑筋咯。
最后,再回顾一下
Model(数据层):存放静态字段、数据存储、模型资源存储
View(视图层):就是用户可以看到的层,指的是可以看到的UI,模型,加载和调用事件
Controller(管理层):实现业务逻辑功能、加载模型资源、功能实现等

2018-10-31 21:52:26 xc54959595 阅读数 98

Unity3D的MVC框架(一)——Strange IOC与Extension的扩展介绍

StrangeIoC框架是一个超轻量级和高度可扩展反转(IOC)框架,专门为c#和Unity编写,它是基于MVC框架扩展的。即MVCS框架。M(models),V(view),C(controller),S(services)。详细的信息可以查看其官方文档。
作为一款依赖注入/控制反转(IOC)的MVC框架,StrangeIoC除了使我们的程序结构更加解耦合理外,还为我们提供了大量方便的功能(这里主要是和PureMVC进行对比)。

Extensions

该框架的应用是以extension的扩展为基础的,主要的扩展如下:

Injection extension

Injection的扩展可以说是松耦合绑定的基础,使逻辑和显示分离得以实现,正如官方文档所言,很多人将StrangeIoc这套框架成为Dependency Injection框架, 这个其实是由Injection扩展来是实现的,具体的类图如下:
在这里插入图片描述

在我们使用Injection的时候,需要注意下列事项

  1. 循环依赖问题,Injection框架可以帮我们检查这样的错误并且抛出异常,但是我们最好在写代码的时候防止这么做,下面就是一个简单的例子,在实际情况中的依赖可能比这个负责,比如,A - >B -> C- >D,而D最后又需要A。
  2. Injection 是利用反射来实现,反射比较慢,我们可以利用ReflectionBinder中的RefectAll提前来完成反射。
  3. 我们必须记住的是,任何的依赖都需要binding去记住mapping,如果我们忘记了增加Binding,就会产生空对象异常, Injection会帮助我们查看这些错误。我们必须记住的是,任何的依赖都需要binding去记住mapping,如果我们忘记了增加Binding,就会产生空对象异常, Injection会帮助我们查看这些错误。

Dispatcher extension

Event Dispatcher 和Singal都可以看作是Dispatcher的扩展,其实就是一种Observer设计模式的松耦合实现。基本的类关系图如下:
在这里插入图片描述

在这里插入图片描述

本质上都是Observer的实现方式,下面的Command extension 和Mediator extension都会用Dispatch将MVC设计模式中的M,V,C联系到一起。

Command extension

Dispatch是将Event绑定在方法上,而Command extension是将Event绑定到具体的Command上,Command的使用应该是MVCS设计模式中的Controller(C),基本类之间的关系如下:
在这里插入图片描述

CommandBinder可以将具体的Event或者Signal来绑定到具体的Command上,其负责利用Event或者Signal来找到,或者创建一个Command。

Mediation extension

Mediation 扩展是整个StrangeIoc框架中唯一依赖Unity3D的API的扩展,这是因为mediation是用于处理显示(Views,GameObject)和除显示外的应用程序逻辑的。在这个框架中,其把显示部分分成了View和Mediator,具体的类层次关系如下:
在这里插入图片描述

Context extension

Context extension 是整个strangeIoc 的MVCS框架应用的基础,其组合了前面所有的extension,具体的关系如下图 :
在这里插入图片描述

关于StrangeIOC框架的具体用法,在下一节我们会具体介绍。

参考文章链接:https://blog.csdn.net/leoleocs/article/details/48023823

Unity MVC框架 StrangeIoC

博文 来自: qq_43667968
没有更多推荐了,返回首页