虚幻引擎基础入门(C++) — 【代理说明 09】

虚幻引擎基础入门(C++) — 【代理说明 09】


上一篇:虚幻引擎基础入门(C++) — 【资源加载 08】

前言

  1. 代理可以解决一对一或一对多的任务分配工作,还可以解决通知问题
  2. 通过代理完成调用某一个对象的一个函数,而不直接持有该对象的任何指针
  3. 要调用某个函数,但并不直接去调用,而是通过另一个入口去调用,这就是代理

代理分为:

单播代理(只能进行通知一个人)
多播代理(可以进行多人通知)
动态代理(可以被序列化,体现在可与蓝图进行交互,C++中可以将通知事件进行蓝图广播)


提示:以下是本篇文章正文内容,下面案例可供参考

一、单播代理

  1. 单播代理只能绑定一个通知对象,无法进行多个对象通知

  2. 通过宏进行构建,分为两种:

    1.有返回类型
    2.没有返回类型

  3. 常用绑定函数:

    1.BindUObject:绑定UObject类型对象成员函数的代理
    2.BindSP:绑定基于共享引用的成员函数代理
    3.BindRaw:绑定原始自定义对象成员函数的代理,操作调用需要注意执行需要检查IsBound
    4.BindStatic:绑定全局函数成为代理
    5.UnBind:解除绑定代理关系
    6.绑定中传递的对象类型必须和函数指针所属类的类型相同,否则绑定会报错

  4. 调用执行:

    1.执行Execute函数之前,需要检查是否存在有效绑定使用函数 IsBound
    2.Execute 调用代理通知,不安全
    3.ExecuteIfBound 调用代理通知,安全,但是有返回类型的回调函数无法使用此函数执行回调
    4.IsBound 检查当前是否存在有效代理绑定

  5. 构建步骤:

    1.通过宏进行声明代理对象类型(根据回调函数选择不同的宏)
    2.使用代理类型进行构建代理对象
    3.绑定回调对象、操作函数
    4.执行代理对象回调

    //(在.h文件中)
    
    //1.构建单播代理(此例以无参无返单播代理为例)
    //① 单播代理:无参数无返回值单播代理
    DECLARE_DELEGATE(CallTest)
    //② 1个参数的单播代理
    DECLARE_DELEGATE_OneParam(Delegate_OneP, int32)
    //③ 2个参数的单播代理
    DECLARE_DELEGATE_TwoParams(Delegate_TwoP, int32, int32)
    //④ 有返回值,和2个参数的单播代理
    DECLARE_DELEGATE_RetVal_TwoParams(float, Delegate_RTwoP, float, float)
    
    
    UCLASS(config=Game)
    class AUECCharacter : public ACharacter
    {
        GENERATED_BODY()
    public:
    
        //2. 声明无参无返的单播代理
        CallTest Dnop;
    
        //3.创建要绑定到无参无返的单播代理上的函数
        void Func();
        virtual void BeginPlay();
    
    };
    
    //(在.cpp文件中)
    
    void AUECCharacter::Func()
    {
        UE_LOG(LogTemp, Log, TEXT("---我是无参无返的单播代理!---"));
    }
    
    
    
    void AUECCharacter::BeginPlay()
    {
        Super::BeginPlay();
    
        //4.将Func函数绑定到单播代理
        Dnop.BindUObject(this, &AUECCharacter::Func);
    
        //5.判断单播代理是否绑定
        if (Dnop.IsBound())
        {
            //6.调用代理,执行绑定的函数
            Dnop.Execute();
        }
    }
    

    输出如下:
    在这里插入图片描述

二、单播代理

  1. 无法构建具有返回值的多播代理,只能构建参数

  2. 广播

    调用函数Broadcast,但是调用不保证执行顺序的正确性

  3. 构建步骤:

    1.使用宏构建代理类型
    2.使用代理类型构建多播代理对象
    3.添加绑定代理
    4.执行调用

    //(在.h文件中)
    
    //1.构建多播代理(不可以构建有返回值的)
    //① 无参的多播代理
    DECLARE_MULTICAST_DELEGATE(Delegate_MultiNoP)
    
    //② 单播代理:有2个参数的单播代理
    DECLARE_MULTICAST_DELEGATE_TwoParams(Delegate_MultiTwoP, int32, int32)
    
    
    UCLASS(config=Game)
    class AUECCharacter : public ACharacter
    {
        GENERATED_BODY()
    public:
    
        //2. 声明多播代理
        Delegate_MultiNoP MultiNoP;
        Delegate_MultiTwoP MultiTwoP;
    
        //3.创建要绑定到无参无返的单播代理上的函数
        void Func1_MultiNoP();
        void Func2_MultiNoP();
    
        void Func1_MultiTwoP(int32 A, int32 B);
        void Func2_MultiTwoP(int32 C, int32 D);
    
        virtual void BeginPlay();
    
    
    };
    
    //(在.cpp文件中)
    
    void AUECCharacter::Func1_MultiNoP()
    {
        UE_LOG(LogTemp, Log, TEXT("---------我是无参的多播代理Func1_MultiNoP()!---------"));
    }
    
    
    void AUECCharacter::Func2_MultiNoP()
    {
        UE_LOG(LogTemp, Log, TEXT("---------我是无参的多播代理Func2_MultiNoP()!---------"));
    }
    
    
    void AUECCharacter::Func1_MultiTwoP(int32 A, int32 B)
    {
        UE_LOG(LogTemp, Log, TEXT("---------我是有2个int参AB的多播代理Func1_MultiTwoP!---------"));
    }
    
    
    void AUECCharacter::Func2_MultiTwoP(int32 C, int32 D)
    {
        UE_LOG(LogTemp, Log, TEXT("---------我是有2个int参CD的多播代理Func1_MultiTwoP!---------"));
    }
    
     
    
    void AUECCharacter::BeginPlay()
    {
        Super::BeginPlay();
    
        //4.将多个函数绑定到多播代理
        MultiNoP.AddUObject(this, &AUECCharacter::Func1_MultiNoP);
        MultiNoP.AddUObject(this, &AUECCharacter::Func2_MultiNoP);
    
        MultiTwoP.AddUObject(this, &AUECCharacter::Func1_MultiTwoP);
        MultiTwoP.AddUObject(this, &AUECCharacter::Func2_MultiTwoP);
    
        //5.判断多播代理是否绑定
        if (MultiNoP.IsBound())
        {
            //6.调用多播代理,执行绑定的函数
            MultiNoP.Broadcast();
        }
    
        //5.判断多播代理是否绑定
        if (MultiTwoP.IsBound())
        {
            //6.调用多播代理,执行绑定的函数
            MultiTwoP.Broadcast(2,3);
        }
    
        //清空所有绑定函数
        MultiNoP.Clear();
    
        //移除单绑定,需要传递 FDelegateHandle(代理句柄)
        FDelegateHandle DH_Fun = MultiTwoP.AddUObject(this, &AUECCharacter::Func1_MultiTwoP);
        MultiTwoP.Remove(DH_Fun);
    
        //移除某个对象中的所有函数绑定
        MultiTwoP.RemoveAll(this);
    
    
    }
    

    输出如下:
    在这里插入图片描述

三、动态代理

  1. 是允许被序列化的数据结构(代理可以被数据化提供给蓝图进行使用),使得可以在.cpp中调用代理广播,并将事件通知到蓝图

  2. UE中的大部分通知事件均使用动态代理,方便蓝图操作(如碰撞通知)

  3. 动态代理无法使用带有返回值的函数进行构建

  4. 动态代理分为

    1.动态单播(但是创建动态单播还不如创建普通的多播,单播无法在蓝图中绑定,无法使用宏BlueprintAssignable修饰)
    2.动态多播

  5. 动态代理与上面单播多播的区别:

    1.动态代理的类型名称需要用 F 开头(动态代理实现了机制构建类)
    2.动态代理对象类型可以使用UPROPERTY标记;其他代理均无法使用(不加编译可过,调用就会出错)
    3.动态代理绑定对象的函数需要使用UFUNCTION进行描述(因为需要跟随代理被序列化)

  6. 构建步骤

    1.通过宏进行声明代理对象类型(根据回调函数选择不同的宏)
    2.使用代理类型进行构建代理对象
    3.绑定回调对象、操作函数
    4.执行代理对象回调

总结

以上就是今天要讲的内容,本文仅仅简单介绍了虚幻引擎中的代理说明使用。

至此虚幻引擎基础入门(C++)系列就完毕啦,接下来敬请期待!!!

未完待续!

如有帮助给个关注吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GIS子枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值