【UGF】(四)自定义框架组件和游戏逻辑事件

毕设项目需要用到UNet,而UNet有大量的回调函数,需要在回调时进行相应的逻辑处理

例如匹配房间列表会回调NetworkLobbyManager.OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList),  需要根据回调函数传来的信息进行逻辑处理。如果直接在回调函数中写逻辑代码就会显得逻辑混乱,脱离了UGF的模块化思想。UGF的Procedure是专门用来分离逻辑的,我希望UNet所有的回调可以通过EventComponent.Subscribe()来订阅,并统一在Procedure中进行逻辑处理。

一.自定义事件类

例如UGF内置的打开UI成功事件,Subscribe第一个参数是事件分发ID,第二个参数是回调函数。OpenUIFormSuccessEventArgs类相当于一个桥梁,用于传递变量,比如我们可以在回调事件中访问成功打开的这个UIForm,这样就可以在打开成功后对该UIForm进行初始化。

UGF.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess);
private void OpenUIFormSuccess(object sender, GameEventArgs e)
        {
            OpenUIFormSuccessEventArgs uiEvent = (OpenUIFormSuccessEventArgs)e;
            Log.Info("Open UIForm({0}) Success",uiEvent.UIForm.UIFormAssetName);
        }

以自定义MatchList为例:

①首先创建一个事件类继承GameFramework.Event.GameEventArgs

②重写基类抽象方法,其中Id是事件Id, Clear()清理事件

③添加事件需要的变量,匹配游戏房间回调函数OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList)包含的参数都需要定义在事件类中以实现参数传递

④初始化事件变量,Fill(arg0,arg1....)函数是为了把OnMatchList回调方法的形参赋值给事件对应的变量

using GameFramework.Event;
using System.Collections.Generic;
using UnityEngine.Networking.Match;

namespace ShadowTank
{
    public sealed class UNetMatchListEventArgs : GameEventArgs
    {
        public static readonly int EventId = typeof(UNetMatchListEventArgs).GetHashCode();

        public override int Id
        {
            get
            {
                return EventId;
            }
        }
        public bool Success { get; private set; }
        public string ExtendedInfo { get; private set; }
        public List<MatchInfoSnapshot> MatchList { get; private set; }

        public override void Clear()
        {
            Success = false;
            ExtendedInfo = default(string);
            MatchList = null;
        }
        public UNetMatchListEventArgs Fill(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList)
        {
            Success = success;
            ExtendedInfo = extendedInfo;
            MatchList = matchList;
            return this;
        }
    }
}

二、设置事件的唤醒环境

我希望NetworkLobbyManager.OnMatchList()回调时会调用已订阅的UNetMatchListEventArgs事件

①新建一个类继承UnityEngine.Networking.NetworkLobbyManager并重写OnMatchList方法

②定义引用委托链表头和事件成员的增/减:

private EventHandler<UNetMatchListEventArgs> m_MatchListEventHandler;
public event EventHandler<UNetMatchListEventArgs> UNetMatchList
        {
            add
            {
                m_MatchListEventHandler += value;
            }
            remove
            {
                m_MatchListEventHandler -= value;
            }
        }

③在OnMatchList方法执行委托,ReferencePool.Acquire是从引用池获取对象,如果没有会自动创建:

public override void OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList)
        {
            base.OnMatchList(success, extendedInfo, matchList);
            if(null!=m_MatchListEventHandler)
            {
                lock (m_MatchListEventHandler)
                {
                    m_MatchListEventHandler(this, ReferencePool.Acquire<UNetMatchListEventArgs>().Fill(success, extendedInfo, matchList));
                }
            }
        }

撸了这么多代码你以为这就算搞定了?那你就太小看UGF的上手难度了,本着UGF一贯对新手不友好的作风,你可能得花两天时间来自定义一个逻辑事件

三、自定义框架组件

我需要将NetworkLobbyManager的功能封装到框架组件,方便管理和模块间的访问。

①新建一个类继承UnityGameFramework.Runtime.GameFrameworkComponent

②抛出事件(将事件添加到事件队列)

using UnityEngine;
using GameFramework;
using UnityGameFramework.Runtime;
using System;

namespace ShadowTank
{
    public class UNetComponent : GameFrameworkComponent
    {
        [SerializeField]
        private UNetLobbyManager m_LobbyManager = null;
        protected override void Awake()
        {
            base.Awake();
            m_LobbyManager.UNetMatchList += OnMatchList;
        }

        private void OnMatchList(object sender, UNetMatchListEventArgs e)
        {
            //抛出事件
            UGF.Event.Fire(this, e);
        }
    }
}

是不是有点乱?乱就对了。来捋捋思路,我们在UNetComponet类中把UNetComponet.OnMatchList()方法通过“m_LobbyManager.UNetMatchList += OnMatchList“附加给了委托UNetLobbyManager.m_MatchListEventHandler,这时候m_MatchListEventHandler非空,所以UNetLobbyManager.OnMatchList()回调时会执行m_MatchListEventHandler委托,相当于执行了UNetComponet.OnMatchList()把事件抛出,事件池中已订阅的事件就会被调用。

四、订阅自定义逻辑事件并验证

为了验证自定义逻辑事件是不是能用,写个Procedure订阅一个事件看看是否成功调用:

protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
        {
            base.OnEnter(procedureOwner);
                   UGF.Event.Subscribe(UNetMatchListEventArgs.EventId, (object sender, GameEventArgs e) => {
                var info = (UNetMatchListEventArgs)e;
                Log.Info("匹配游戏房间是否成功:{0}",info.Success);
            });
        }
验证成功!自定义逻辑事件就是这么..........................简单(mmp,写了这么多装个13不介意吧)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值