Unityフレームワーク学習_DataManager、イベントベースの情報管理駆動システム、情報変更後のグローバルリフレッシュをシンプルかつ迅速に実現
目次
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によって作成されました。お勧めします。私もグループにいます!
この記事はオリジナル記事ですので、有名作家の出典を転載してトップにこだわってください!!!!