Unityフレームワーク学習_DataManager、イベントベースの情報管理駆動システム、情報変更後のグローバルリフレッシュをシンプルかつ迅速に実現

              Unityフレームワーク学習_DataManager、イベントベースの情報管理駆動システム、情報変更後のグローバルリフレッシュをシンプルかつ迅速に実現


目次

1.ブログ投稿の概要

2.コンテンツ

(1)データマークDataType

  (2)コアスクリプトデータベース

  (3)コアスクリプトDataManger

(4)演示Demo

3.プッシュ

4.結論


1.ブログ投稿の概要

このブログでは、イベントベースの情報管理ドライブシステムを紹介しています。次の図に示すように、プロジェクトを作成するときに、いくつかの依存関係に遭遇することがよくあります。

       バックパックにはゴールドコインデータコインが入っています。1ページ目はゴールドコインの数を表示する必要があります。2ページ目はゴールドコインの数に応じて特定のアイテムの購入を開始します。3ページ目は数に応じていくつかのレベル変更を変更します。コインの価値はその場で変更され、他の3ページもそれに応じて変更する必要があります。最も直接的な方法は、3ページを直接参照して手動で変更することです。これの欠点は、コード、相互参照、およびコードはますます複雑になります。より複雑になると、このブログ投稿の目的は、情報が変更された後のグローバル更新を迅速かつ簡単に実現することです。コインが変更された後、通知がに送信されます。関連する場所を自動的に変更します。ブロガーの以前のEventMangerを読んでいない場合は、そこにジャンプできます。1つの記事を見てください。この記事は、前の記事に基づいています。

 


2.コンテンツ

(1)データマークDataType

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

       プレーヤー情報UsrInfo、敵情報EnemyInfoなど、多くの情報データテーブルがある場合があります。最初に列挙型DataTypeを記述します。列挙は、データを区別して取得するためのさまざまなデータのマークとして使用されます。

  (2)コアスクリプトデータベース

/// <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列挙型
OnInit() 初期化の方法として、構築中に呼び出され、構築中に実行されます
Notify() ブロードキャスト方式では、データが変更されたときに手動でトリガーしてブロードキャストを送信します
データベース() データ情報全体を登録し、構築中にDataManagerにマークを付けて、DataManagerとマークを介してどこからでもデータを取得できるようにします。

(3)コアスクリプト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 EventMgrをインスタンス化し、デリゲートインスタンスを使用してrefreshメソッドをバインドします
BindEvent() 製本方法

 

  (3)コアスクリプト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 すべてのデータ情報は辞書に保存され、データの作成時に追加されます
EventMgrDict ディクショナリには、データマークと、マークに対応するrefreshメソッドにバインドされたデリゲートが格納されます。
AddDataWatch() 現在のスクリプトは、特定のデータのタグに監視メソッドを追加します。タグのデータがブロードキャストされると、そのメソッドは自動的に呼び出されます。
登録() タグとデータをキーと値のペアとしてEventListerDictに保存します
取得する() マークを付けて、EventListerDictから対応するデータを取得します

 

(4)演示Demo

        特定の使用法を示すシナリオをシミュレートします。文字情報スクリプトUserInfoには金貨データ100が含まれ、OnePanelページは金貨の数を表示するために使用されます。TwoPanelページは金貨を増減できます。金貨が500に達すると色が変わります。

タグを追加する:

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

情報スクリプト: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);
	}
}

ページ1スクリプト: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);
	}
}

2ページ目のスクリプト: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.プッシュ

プロジェクトのデモ:https//github.com/KingSun5/Study_DataManager


4.結論

       私はたくさん書いていますが、あまりありません。論理は非常に単純です。ブロガーの記事がうまく書かれていると思うなら、ブロガーに注意を払い、ブログ投稿を好きになるかもしれません。さらに、ブロガーの能力は記事に誤りがある場合は、すべてのコメントと批判を歓迎します。

       QQ交換グループ:806091680(中国人)

       このグループは、CSDNブロガーのChinarによって作成されました。お勧めします。私もグループにいます!

       この記事はオリジナル記事ですので、有名作家の出典を転載してトップにこだわってください!

おすすめ

転載: blog.csdn.net/Mr_Sun88/article/details/93372075