Unity 프레임 워크 학습 _DataManager, 이벤트 기반 정보 관리 구동 시스템, 정보 변경 후 글로벌 새로 고침을 간단하고 빠르게 실현
목차
1. 블로그 게시물 소개
이 블로그는 이벤트 기반 정보 관리 드라이브 시스템을 소개합니다. 다음 그림과 같이 프로젝트를 작성할 때 종종 몇 가지 종속성이 발생합니다.
백팩에는 금화 데이터 코인이 있습니다 .1 페이지는 금화의 개수를 표시해야합니다 .2 페이지는 금화의 개수에 따라 특정 아이템을 구매할 수 있습니다 .3 페이지는 개수에 따라 일부 레벨 변경을 수정합니다. 코인의 가치는 제자리에서 수정되고 나머지 3 페이지는 그에 따라 변경되어야합니다. 가장 직접적인 방법은 3 페이지를 직접 참조하여 수동으로 수정하는 것입니다. 이의 단점은 코드, 상호 참조 및 코드는 점점 더 복잡해질 것입니다. 복잡할수록이 블로그 게시물의 목적은 정보 변경 후 글로벌 리프레시를 빠르고 쉽게 실현하는 것입니다. 코인이 변경되면 다음 주소로 알림이 전송됩니다. 관련 장소를 자동으로 수정합니다. 블로거의 이전 EventManger를 읽지 않았다면 바로 이동할 수 있습니다. 한 기사를 살펴보면이 기사는 이전 기사를 기반으로합니다.
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 () | 생성 중 호출, 초기화 방법으로 생성 중 실행 |
알림 () | 브로드 캐스트 방법, 데이터가 변경되면 수동으로 트리거하여 브로드 캐스트를 보냅니다. |
데이터 베이스() | 구축시 전체 데이터 정보를 등록하고 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 인스턴스, 대리자 인스턴스를 사용하여 새로 고침 메서드 바인딩 |
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 | 사전은 데이터 마크와 마크에 해당하는 새로 고침 메서드에 바인딩 된 대리자를 저장합니다. |
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가 만들었습니다. 추천합니다! 나도 그룹!
이 기사는 원본 기사이며, 저명한 작가의 출처를 다시 인쇄하고 상단에 집착하세요! ! ! !