找回密码
 立即注册
查看: 569|回复: 0

Unreal在Detail中绑定事件

[复制链接]
发表于 2020-12-9 07:54 | 显示全部楼层 |阅读模式
首先安利一下我的插件
Unreal中的MulticastDelegate

      使用DECLARE_DYNAMIC_MULTICAST_DELEGATE系列宏(或者加个sparse)声明,并能够通过UPROPERTY标记进入反射系统,本插件主要针对的就是这类Delegate,这些宏本身不产生代码,而是被反射系统收集后自动生成。
      其中DECLARE_DYNAMIC_MULTICAST_DELEGATE产生的Delegate继承于TMulticastScriptDelegate,通过一个TScriptDelegate的数组来存储Delegate,而TScriptDelegate中存有一个WeakObjectPtr以及函数的名字,调用时通过ProcessEvent反射调用事件
      而DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE产生的Delegate将事件存储于一个全局的Map中,这类Delegate只存储一个bool值因此更节省空间,但是在添加,删除时性能会低于前者
     其中前者并未提供序列化的函数,后者因为存储于全局变量中,所以也并不利于实现序列化,因此,Unreal中的Delegate只能通过书写C++代码或蓝图来做运行期绑定,所以无法简单无法实现类似Unity那样的Inspector面板绑定。
为什么要开发这个功能

      最近在撸VR项目的时候,写了一个3DUI,然后计划将它作为一个通用的触发器,用来触发场景中各个Actor的事件,当时主要设想了以下方案。
    接口,但是TScriptInterface并无法在Detail上Pick对象,PickActor的话又无法过滤那些没有实现接口的对象,而且当Actor有多个需要用于通知的函数时,就需要通过接口传递一个Enum或者FName,写起来得两边确认,很不舒适。转发器,写一个Actor做事件转发,这样就无需传递Enum或FName,但是这样会产生大量的类,而且多一个Actor很丑直接多态,这样干掉了转发器,直接通过子类绑定事件,但是事件一共有四十多种,也就是要创建四十多张蓝图,很不优雅。反射调用,直接填写目标函数的名字,最优雅的一种方式,但是容易发生发生错误,且不够方便,但是可以通过定制Detail改良。
      既然都考虑定制Detail面板了,那我何不实现一个类似UnityEventSystem的绑定器呢。
数据存哪儿

      既然Delegate无法序列化,那么我必须找个地方去存储我们编辑的绑定信息,由于绑定的信息必定存在于World中的Actor,所以我们选取了UAssetUsetData作为数据存储。
      ULevel作为一个Asset,理所当然的实现了IInterface_AssetUserData
      在AssetUserData中存储了一个PerActor的绑定表
如何绑定

      我们希望Event在World加载之初就完成绑定,最佳的非侵入方案就是UWorldSubsystem的Initialize,在Initialize中我们收集World中所有的Level并绑定事件
      _ApplyLevelBindInfo实现如下
      对于当前无法找到绑定对象的绑定项,我们将它存到LostReferenceItems中,等待其它StreamingLevel加载时再行绑定
跨Level绑定

      为了实现跨关卡绑定,我们监听了LevelAddedToWorld和LevelRemovedFromWorld,代码如下
      _TryApplyItemsLostReference中还处理了发出事件Actor被销毁的情况,由于LostReferenceItems加入了反射系统,所以UE会为我们处理引用
注入Detail

      我们希望对于任意Actor都能绑定事件,并且无需额外代码,我一开始的想法是提供一个EventBindComponent,通过添加Component的方式来实现绑定效果,但是这种方式不够优雅,而且选中Actor后还要再选中Component的操作有点烦人,于是我们虚晃一枪,"利用"Unreal的反射系统实现了Detail注入。
      首先准备一个本体------一个空的Struct
      然后我们在StartupModule为Actor强行加入一个Struct
      再注册Property的扩展就大功告成了
      至此,我们为Unreal实现了一个简单的EventBinder

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-24 07:14 , Processed in 0.123043 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表