Unity framework learning _DataManager, event-based information management driving system, simple and quick to realize global refresh after information changes

              Unity framework learning _DataManager, event-based information management driving system, simple and quick to realize global refresh after information changes


table of Contents

1. Introduction to the blog post

2. Content

(1) The data mark DataType

  (2) Core script Database

  (3) Core script DataManger

(4) Demonstration Demo

3. Push

4. Conclusion


1. Introduction to the blog post

This blog introduces the event-based information management drive system. We often encounter some dependencies when writing projects, as shown in the following figure:

       There is a gold coin data Coin in the backpack. Page 1 needs to display the number of gold coins. Page 2 will open the purchase of certain items according to the number of gold coins. Page 3 will modify some level changes according to the number of gold coins. The value of Coin is modified in place, and the other three pages should be changed accordingly. The most direct way is to directly reference the three pages to modify manually. The disadvantage of this is that it causes the coupling of the code, mutual reference, and the code will become more and more complicated. The more complex, the purpose of this blog post is to quickly and easily realize the global refresh after the information changes. After the Coin changes, a notification will be sent to automatically modify the related places. If you haven't read the blogger’s previous EventManger, you can jump to it. Take a look at one article, this article is based on the previous one.

 


2. Content

(1) The data mark DataType

/// <summary>
/// 数据类型
/// </summary>
public enum DataType
{
   UserInfo = 1001,
   EnemyInfo = 1002,
}

       We may have a lot of information data tables, such as player information UsrInfo, enemy information EnemyInfo, we first write an enumeration type DataType, the enumeration is used as a mark of different data to distinguish and obtain data.

  (2) Core script Database

/// <summary>
/// time:2019/6/21 16:36
/// author:Sun
/// des:数据驱动基类
///
/// github:https://github.com/KingSun5
/// csdn:https://blog.csdn.net/Mr_Sun88
/// </summary>
public abstract class DataBase
{

	/// <summary>
	/// 数据类型
	/// </summary>
	public abstract DataType InDataType { get;}

	/// <summary>
	/// 初始化
	/// </summary>
	public abstract void OnInit();
	
	/// <summary>
	/// 广播自身
	/// </summary>
	public abstract void Notify();

	/// <summary>
	/// 构造函数内注册自己
	/// </summary>
	public DataBase()
	{
		OnInit();
		DataManager.Instance.Register(InDataType,this);
	}
}
InDataType DataType enumeration type, as a mark of different data
OnInit() Called during construction, as a method of initialization, executed during construction
Notify() Broadcast method, when the data changes, manually trigger to send out a broadcast
DataBase() Register the entire data information and mark into the DataManager during construction, so that the data can be obtained anywhere through the DataManager and mark

(3) Core script DataEvent

/// <summary>
/// time:2019/6/23 13:13
/// author:Sun
/// des:事件封装
///
/// github:https://github.com/KingSun5
/// csdn:https://blog.csdn.net/Mr_Sun88
/// </summary>
public class DataEvent
{
	/// <summary>
	/// 实例事件
	/// </summary>
	public  EventMgr InstanceEvent;

	/// <summary>
	/// 绑定方法
	/// </summary>
	/// <param name="eventMgr"></param>
	public void BindEvnt(EventMgr eventMgr)
	{
		InstanceEvent += eventMgr;
	}
}
InstanceEvent Instance an EventMgr, use the delegate instance to bind the refresh method
BindEvent () Binding method

 

  (3) Core script DataManger

/// <summary>
/// 数据管理成员接口
/// </summary>
public interface IDataMgr
{

	Dictionary<DataType, DataBase> EventListerDict { get; set; }//存储注册的信息
	
	Dictionary<DataType, DataEvent> EventMgrDict { get; set; }//存储绑定事件信息
	
	void AddDataWatch(DataType dataType,EventMgr eventMgr);//绑定更新方法
	
	void Register(DataType dataType, DataBase dataBase);//注册数据信息

	DataBase Get(DataType dataType);//获取数据

}
/// <summary>
/// time:2019/6/21 16:37
/// author:Sun
/// des:数据驱动管理
///
/// github:https://github.com/KingSun5
/// csdn:https://blog.csdn.net/Mr_Sun88
/// </summary>
public class DataManager:IDataMgr
{

	private static DataManager _instance;

	public static DataManager Instance
	{
		get
		{
			if (_instance==null)
			{
				_instance = new DataManager();
			}
			return _instance;
		}
	}

	public Dictionary<DataType, DataBase> EventListerDict { get; set; }
	
	public Dictionary<DataType,DataEvent> EventMgrDict { get; set; }

	/// <summary>
	/// 绑定数据类监听
	/// </summary>
	/// <param name="dataType"></param>
	/// <param name="eventMgr"></param>
	public void AddDataWatch(DataType dataType, EventMgr eventMgr)
	{
		if (EventMgrDict==null)
		{
			EventMgrDict = new Dictionary<DataType, DataEvent>();
		}
		
		if (EventMgrDict.ContainsKey(dataType))
		{
			//已存在该信息的刷新方法 先移除监听 绑定方法后重新监听
			EventManager.Instance.UnRegister((int)dataType);
			EventMgrDict[dataType].BindEvnt(eventMgr);
			EventManager.Instance.Register((int)dataType,EventMgrDict[dataType].InstanceEvent);
		}
		else
		{
			//不存在该信息的刷新方法,需注册
			var dataEvent = new DataEvent();
			dataEvent.BindEvnt(eventMgr);
			EventMgrDict.Add(dataType,dataEvent);
			EventManager.Instance.Register((int)dataType,dataEvent.InstanceEvent);
		}
	}

	/// <summary>
	/// 注册数据类
	/// </summary>
	/// <param name="dataType"></param>
	/// <param name="dataBase"></param>
	public void Register(DataType dataType, DataBase dataBase)
	{
		if (EventListerDict==null)
		{
			EventListerDict = new Dictionary<DataType, DataBase>();
		}

		if (EventListerDict.ContainsKey(dataType))
		{
			Debug.LogError("Key:"+dataType+"已经被注册!");
			return;
		}
		EventListerDict.Add(dataType,dataBase);	
	}

	/// <summary>
	/// 获取数据类
	/// </summary>
	/// <param name="dataType"></param>
	/// <returns></returns>
	public DataBase Get(DataType dataType)
	{
		if (EventListerDict.ContainsKey(dataType))
		{
			return EventListerDict[dataType];
		}
		Debug.LogError("Key:"+dataType+"不存在,获取失败!");
		return null;
	}
}

 

EventListerDict All data information is stored in the dictionary, which is added when the data is constructed
EventMgrDict The dictionary stores the data mark and the delegate bound to the refresh method corresponding to the mark
AddDataWatch() The current script adds a monitoring method to the tag of a certain data. If the data of the tag is broadcast, the method is automatically called
Register() Store tags and data as key-value pairs in EventListerDict
Get() Obtain corresponding data from EventListerDict by marking

 

(4) Demonstration Demo

        We simulate a scenario to demonstrate specific usage. The character information script UserInfo contains gold coin data 100, the page OnePanel is used to display the number of gold coins, the page TwoPanel can increase or decrease gold coins, and there is a picture that will change color when the gold coins reach 500.

Add tags:

/// <summary>
/// 数据类型
/// </summary>
public enum DataType
{
   UserInfo = 1001,
}

Information script: UserInfo

public class UserInfo : DataBase
{
	/// <summary>
	/// 背包内金币数量
	/// </summary>
	public int CoinTotal;
	
	public override DataType InDataType
	{
		get { return DataType.UserInfo; }
	}

	public override void OnInit()
	{
		CoinTotal = 100;
	}

	public override void Notify()
	{
		EventManager.Instance.Invoke((int)InDataType,this);
	}
}

Page 1 script: OnePanel

using UnityEngine;
using UnityEngine.UI;

public class OnePanel : MonoBehaviour {
	
	/// <summary>
	/// 页面1
	/// </summary>
	public Transform Panel1;
	/// <summary>
	/// 页面2
	/// </summary>
	public Transform Panel2;
	/// <summary>
	/// 金币显示
	/// </summary>
	public Text TxtCoin;
	/// <summary>
	/// 页面跳转
	/// </summary>
	public Button BtnGo;
	/// <summary>
	/// 背包数据
	/// </summary>
	private UserInfo _userInfo;

	// Use this for initialization
	void Start () {
		
		BtnGo.onClick.AddListener(OnClickGo);

		//初始化一下背包数据
		new UserInfo();
		//获取背包数据
		_userInfo = DataManager.Instance.Get(DataType.UserInfo) as UserInfo;
		//初始化金币显示
		TxtCoin.text = _userInfo.CoinTotal.ToString();
		//绑定方法,数据变动后刷新
		DataManager.Instance.AddDataWatch(DataType.UserInfo,OnRefresh);
	}
	
	/// <summary>
	/// 数据变动后的刷新方法
	/// </summary>
	/// <param name="param"></param>
	private void OnRefresh(params object[] param)
	{
		
		//获取广播的数据
		var user = param[0] as UserInfo;
		//更新数据显示
		TxtCoin.text = user.CoinTotal.ToString();
	}
	
	/// <summary>
	/// 跳转页面
	/// </summary>
	private void OnClickGo()
	{
		Panel1.gameObject.SetActive(false);
		Panel2.gameObject.SetActive(true);
	}
}

Page 2 script: TwoPanel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TwoPanel : MonoBehaviour {
	
	/// <summary>
	/// 页面1
	/// </summary>
	public Transform Panel1;
	/// <summary>
	/// 页面2
	/// </summary>
	public Transform Panel2;
	/// <summary>
	/// 金币增加
	/// </summary>
	public Button BtnAdd;
	/// <summary>
	/// 金币减少
	/// </summary>
	public Button BtnReduce;
	/// <summary>
	/// 返回
	/// </summary>
	public Button BtnReturn;
	/// <summary>
	/// 触发图
	/// </summary>
	public Image ImgChange;
	/// <summary>
	/// 背包数据
	/// </summary>
	private UserInfo _userInfo;

	// Use this for initialization
	void Start () {
		//获取背包数据
		_userInfo = DataManager.Instance.Get(DataType.UserInfo) as UserInfo;
		
		BtnAdd.onClick.AddListener(OnClickAdd);
		BtnReduce.onClick.AddListener(OnClickReduce);
		BtnReturn.onClick.AddListener(OnClickReturn);
		
		//绑定方法,数据变动后刷新
		DataManager.Instance.AddDataWatch(DataType.UserInfo,OnRefresh);
	}
	
	/// <summary>
	/// 添加金币
	/// </summary>
	private void OnClickAdd()
	{
		_userInfo.CoinTotal += 100;
		
		//每次变动广播一下数据
		_userInfo.Notify();
	}
	
	/// <summary>
	/// 减少金币
	/// </summary>
	private void OnClickReduce()
	{
		_userInfo.CoinTotal -= 200;
		
		//每次变动广播一下数据
		_userInfo.Notify();
	}
	
	/// <summary>
	/// 返回页面
	/// </summary>
	private void OnClickReturn()
	{
		Panel1.gameObject.SetActive(true);
		Panel2.gameObject.SetActive(false);
	}
	
	/// <summary>
	/// 数据变动后的刷新方法
	/// </summary>
	/// <param name="param"></param>
	private void OnRefresh(params object[] param)
	{
		//获取广播的数据
		var user = param[0] as UserInfo;
		if (user.CoinTotal>=500)
		{
			Debug.Log("2222");
			ImgChange.color = Color.black;
		}
	}
}


3. Push

Project demo: https://github.com/KingSun5/Study_DataManager


4. Conclusion

       I have written a lot, but there is not much. The logic is very simple. If you feel that the blogger’s article is well written, you may wish to pay attention to the blogger and like the blog post. In addition, the blogger’s ability is limited. If there is any error in the article, All comments and criticisms are welcome.

       QQ exchange group: 806091680 (Chinar)

       This group was created by CSDN blogger Chinar, recommend it! I am also in the group!

       This article is an original article, please reprint the source of the famous author and stick to the top! ! ! !

Guess you like

Origin blog.csdn.net/Mr_Sun88/article/details/93372075