20 UE5 UOBject的事件和五大委托

2024-03-28  本文已影响0人  游戏开发程序员

四类委托

委托之间的区别和主要方法

单播委托

单播委托Demo

// 声明两个委托
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);
    }
        // 构造对象 绑定委托和触发委托
        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);
}

多播委托

// 多播委托 不可以有返回值,不然用谁的返回值呢?
DECLARE_MULTICAST_DELEGATE_OneParam(FMyMultDelegate1P, int32);

    // 多播(不可以有返回值,不然用谁的返回值呢?)
    FMyMultDelegate1P MyMultDelegate1P;
        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"));
        // 广播
        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
        }

动态多播委托

// 动态多播:支持在蓝图中使用,类似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的事件

    // OwingType:拥有此Event的类,本例中使用本类:UTestObject
    DECLARE_EVENT_OneParam(UTestObject, FMyEvent, int32);

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

    //将Event设为私有,防止类外直接访问到,起到安全作用
private:
    FMyEvent DelegateEvent;
    // 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);
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读