美文网首页
20 UE5 UOBject的事件和五大委托

20 UE5 UOBject的事件和五大委托

作者: 游戏开发程序员 | 来源:发表于2024-03-28 23:49 被阅读0次

四类委托

  • 官方步骤: 声明代理、绑定函数到代理、代理调用
    单播委托: 绑定单个可调用对象, 支持返回值.
    多播委托: 可以绑定多个可调用对象, 实质是维持了一个单播委托的数组, 调用时一个个调用.没有返回值.
    事件: 其实就是多播委托, 只是比多播委托多了个friend class OwningType;
    动态委托: 同样分为单播和多播. 只能绑定UFUNCTION, 支持序列化, 可在蓝图中使用(UPROPERTY修饰).
委托之间的区别和主要方法

单播委托

  • 只能绑定一个回调函数指针的委托,也只会触发一次。
  • 绑定函数:BindSataic、BindLambda、BindUFunction
  • 执行方面函数:ExecuteIfBound、IsBound、Unbind

单播委托Demo

  • 1 UObject中的声明委托和定义,以及SelfDelegateCallback
// 声明两个委托
DECLARE_DELEGATE(FMyDelegate);
DECLARE_DELEGATE_OneParam(FMyDelegateWithRetValue, int32);

class UTestObject : public UObject
{
    GENERATED_BODY()

public:
    FMyDelegate MyDelegate;

    FMyDelegateWithRetValue MyDelegateWithRetValue;

    void TriggerDelegate();

    UFUNCTION()
    // 绑定到自身的委托回调
    void SelfDelegateCallback(int32 var)
    {
        UE_LOG(LogTemp,Warning,TEXT("SelfDelegate Callback :%d"), var);
    }
  • 2 绑定lambda函数、UFunction 和 全局函数 触发委托和解绑
        // 构造对象 绑定委托和触发委托
        UTestObject* MyObj = NewObject<UTestObject>();

        // BindLambda绑定
        MyObj->MyDelegate.BindLambda([]() {
            // TriggerDelegate 会导致处理委托
            UE_LOG(LogTemp, Warning, TEXT("FMikeTest1::RunTest Delegate triggered!"));
        });
        // 直接执行
        MyObj->MyDelegate.ExecuteIfBound();

        // 绑定 到对象成员函数(必须有UFUNCTION()宏)
        MyObj->MyDelegate1P.BindUFunction(MyObj, FName("SelfDelegateCallback"));
        MyObj->MyDelegate1P.ExecuteIfBound(1);
        if(MyObj->MyDelegate1P.IsBound())
        {
            MyObj->MyDelegate1P.Unbind();
        }

        // 绑定 全局函数
        MyObj->MyDelegate1P.BindStatic(Delegate1PCallback);
        MyObj->MyDelegate1P.ExecuteIfBound(2);

// 全局函数的委托回调
void Delegate1PCallback(int32 var)
{
    UE_LOG(LogTemp,Warning,TEXT("Delegate1PCallback Param :%d"), var);
}

多播委托

  • 1 声明和定义多播委托
  • 多播委托不能有返回值
// 多播委托 不可以有返回值,不然用谁的返回值呢?
DECLARE_MULTICAST_DELEGATE_OneParam(FMyMultDelegate1P, int32);

    // 多播(不可以有返回值,不然用谁的返回值呢?)
    FMyMultDelegate1P MyMultDelegate1P;
  • 2 添加回调触发函数 全局函数 成员函数 和 Lambda函数
        UTestObject* pUObject = NewObject<UTestObject>();

        // 1 BindLambda绑定
        pUObject->MyMultDelegate1P.AddLambda([](int32 n) {
            UE_LOG(LogTemp,Warning,TEXT("From:BindLambda Callback :%d"), n);
        });

        // 2 绑定全局函数 第二次移除
        FDelegateHandle Handle = pUObject->MyMultDelegate1P.AddStatic(Delegate1PCallback);

        // 3 绑定到对象成员函数(必须有UFUNCTION()宏)
        pUObject->MyMultDelegate1P.AddUFunction(pUObject, FName("SelfDelegateCallback"));
  • 3 广播、移除 和 清空
  • FDelegateHandle Handle此句柄用来移除时需要
        // 广播
        if(pUObject->MyMultDelegate1P.IsBound())
        {
            pUObject->MyMultDelegate1P.Broadcast(666);
            // 通过句柄 移除全局函数回调
            pUObject->MyMultDelegate1P.Remove(Handle); 
            pUObject->MyMultDelegate1P.Broadcast(666);
            // 删除pUObject对象上的回调SelfDelegateCallback
            pUObject->MyMultDelegate1P.RemoveAll(pUObject); 
            pUObject->MyMultDelegate1P.Broadcast(666); // 余下Lambda
        }

动态多播委托

  • 动态多播用法类似多播委托
  • 可支持蓝图的回调.
  • AddDynamic绑定的方法得被UFUNCTION标记,否则绑定无效
  • 代理对象用UPROPERTY标记,并设置BlueprintAssignable,暴露给蓝图使用
// 动态多播:支持在蓝图中使用,类似EventDispatcher
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDynamicMulticastDelegate1P, int32, num);

    // 动态多播
UPROPERTY(BlueprintAssignable) // 添加此标记,蓝图才可用
FDynamicMulticastDelegate1P MyDynamicDe1P;


    // 动态多播委托 支持蓝图里回调
    if(1)
    {
        UTestObject* pUObject = NewObject<UTestObject>();

        // 只能绑定到对象成员函数(必须有UFUNCTION()宏)
        pUObject->MyDynamicDe1P.AddDynamic(pUObject, &UTestObject::SelfDelegateCallback);

        // 广播
        if(pUObject->MyDynamicDe1P.IsBound())
        {
            pUObject->MyDynamicDe1P.Broadcast(1);
            // 解除指定
            pUObject->MyDynamicDe1P.RemoveDynamic(pUObject, &UTestObject::SelfDelegateCallback);
            pUObject->MyDynamicDe1P.Broadcast(2);
            pUObject->MyDynamicDe1P.Clear(); // 全部解绑
            pUObject->MyDynamicDe1P.Broadcast(3);
        }
    }

UOBject的事件

  • 底层实现是一个多播委托 Multicast Delegate。
  • 只能够通过声明它的对象来BoardCast、IsBound、Clear
  • 传进来的OwningType其实就是绑定的ClassType,声明为它的友元类,这样一来这个OwningClass就对这个Event的成员有完全Public的访问权限。
  • 通常用法:将Event定义于类内,设为私有,类外通过公开的访问接口进行绑定,触发,解绑,
  • 这种方式起到了保护隐私的作用
    // OwingType:拥有此Event的类,本例中使用本类:UTestObject
    DECLARE_EVENT_OneParam(UTestObject, FMyEvent, int32);

    //公开对Event对象的访问接口
    FMyEvent& GetEvent() { return DelegateEvent; }

    //将Event设为私有,防止类外直接访问到,起到安全作用
private:
    FMyEvent DelegateEvent;
  • 通过把Evnet绑定在对象上,声明为它的友元类
  • 来达到 只能通过对象来BoardCast、IsBound、Clear的封装性
    // Evnet事件(绑定在某对象上)
    if(1)
    {
        UTestObject* pUObject = NewObject<UTestObject>();

        // 1 BindLambda绑定
        pUObject->GetEvent().AddLambda([](int32 n) {
            UE_LOG(LogTemp, Warning, TEXT("From:BindLambda Callback :%d"), n);
            });

        // 2 绑定全局函数
        pUObject->GetEvent().AddStatic(Delegate1PCallback);

        // 3 绑定到对象成员函数(必须有UFUNCTION()宏)
        pUObject->GetEvent().AddUFunction(pUObject, FName("SelfDelegateCallback"));

        // 触发广播
        if (pUObject->GetEvent().IsBound())
        {
            pUObject->GetEvent().Broadcast(666);
            pUObject->GetEvent().Clear(); // 全清
            pUObject->GetEvent().Broadcast(5);
        }
    }

相关文章

  • UE4对象系统_UObject&UClass

    UObject UObject为对象系统的基类。类层次为: UObjectBase和UObjectBaseUtil...

  • 委托和事件

    区别: 委托是类型,事件是对象; 事件内部就是一个private的委托和add、remove两个方法; 委托可以在...

  • 委托和事件

    using System; using System.Collections.Generic; using Sys...

  • 委托和事件

    委托 委托是一个类,它定义了方法的类型,使得方法可以当做另一种方法的参数传递,就是方法的参数是一个委托变量,在调用...

  • jQuery事件委托和JS事件委托

    jQuery事件委托没得说,直接用on的方式在事件类型参数的后边加一个真正触发事件的对象即可,同时jQuery提供...

  • javascript事件委托和jquery事件委托

    元旦过后,新年第一篇。初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己...

  • 事件委托

    ------------------事件委托----------------- 事件: 事件委托: 原理: 冒泡 ...

  • 2017 10 30

    今天老师主要讲解了:委托和事件、委托的定义、声明、事件的定义,事件发布者的定义等内容。 委托的定义语, 返回类型 ...

  • web前端面试题@六(事件委托)

    *说到事件委托,我们首先先要知道什么是事件委托—— · 那么什么是事件委托呢??? JS里的事件委托就是当事件...

  • 事件对象和事件委托

    事件对象事件发生的详细信息 在ie和chrome 事件详细信息保存到内置的 event对象中Event 对象代表事...

网友评论

      本文标题:20 UE5 UOBject的事件和五大委托

      本文链接:https://www.haomeiwen.com/subject/qdjttjtx.html