User Tag List

Results 1 to 21 of 21

Thread: C++ Event dispatchers: How do we implement them?

  1. #1
    0

    C++ Event dispatchers: How do we implement them?

    Can we create event dispatchers in C++ and then expose them to blueprints which inherit from the C++ class?

    If so, what would be the appropriate reflection macro to use for it?

  2. #2

  3. #3
    2
    Mythic






    Join Date
    Jul 2014
    Posts
    2,250
    Hey there,

    it happens that i did this 2 days ago. Since i want code examples in the docs, i will give you a small code example on how to setup a delegate
    to be used in Blueprints and C++.

    First you need to add your Delegate through the macro in your classes header file:

    Code:
    DECLARE_DYNAMIC_MULTICAST_DELEGATE(FTestDelegate);
    "FTestDelegate" represents the Typename of your upcomming delegates.
    You can use Params by adding _OneParam or _TwoParams and so on at the end.

    Code:
    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FTestDelegate, PARAMTYPE, PARAMNAME);
    
    Example:
    
    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FTestDelegate, float, Damage);
    You place this outside of your class declaration(example):

    Code:
    #pragma once
    
    #include "GameFramework/PlayerController.h"
    #include "MyPlayerController.generated.h"
    
    /**
     * 
     */
    
    DECLARE_DYNAMIC_MULTICAST_DELEGATE(FTestDelegate);
    
    UCLASS()
    class SOCKETTEST_API AMyPlayerController : public APlayerController
    {
    	GENERATED_UCLASS_BODY()
    	
    	
    public:
    	virtual void Tick(float DeltaTime) override;
    	virtual void BeginPlay() override;
    
            void TestFunction();
    
    	UPROPERTY(BlueprintAssignable, Category = "Test")
    		FTestDelegate OnTestDelegate;
    };
    Now you should have spotted the UPROPERTY at the bottom of my example.
    This is the part you add a Delegate (here called "OnTestDelegate").
    The UPROPERTY "BlueprintAssignable" give you the possibility to bind/assign
    this function to a custom event in your BP Child class.

    You should be able to bind a delegate in C++ AND Blueprint and call both
    bound functions/events through c++.

    Code:
    UPROPERTY(BlueprintAssignable, Category = "Test")
    	FTestDelegate OnTestDelegate;
    If you want to add a function to it, you need to call "AddDynamic" on the delegate.
    The editor won't show you this and maybe shows an error. Just try to compile anyway....

    Here is an example for the normal, non param delegate from above, inside your CPP File:

    Code:
    OnTestDelegate.AddDynamic(this, &AMyPlayerController::TestFunction);
    If you now want to call your delegate inside your code do this at the desired position:

    Code:
    OnTestDelegate.Broadcast();

    I hope this helps (:
    Last edited by eXi; 03-07-2015 at 07:06 AM.
    Open for contracted work | Blueprints | UE4++/C++ | Training | VR | My Website

    My UE4 Blog/Page with Free Learning Projects and more: Hit me for ALL the things!

    BP Multiplayer Lobby System: [Released] Support Thread! | BP Multiplayer Crafting System: [Released] Support Thread!

  4. #4
    0
    Hello,

    New to UE4 c++ API.

    How do I subscribe to OnTestDelegate from a different c++ actor.

    Thank you,
    Nihal Kenkre.

  5. #5
    0
    Quote Originally Posted by eXi View Post
    Hey there,

    it happens that i did this 2 days ago. Since i want code examples in the docs, i will give you a small code example on how to setup a delegate
    to be used in Blueprints and C++.

    First you need to add your Delegate through the macro in your classes header file:

    Code:
    DECLARE_DYNAMIC_MULTICAST_DELEGATE(FTestDelegate);
    "FTestDelegate" represents the Typename of your upcomming delegates.
    You can use Params by adding _OneParam or _TwoParams and so on at the end.

    Code:
    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FTestDelegate, PARAMTYPE, PARAMNAME);
    
    Example:
    
    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FTestDelegate, float, Damage);
    You place this outside of your class declaration(example):

    Code:
    #pragma once
    
    #include "GameFramework/PlayerController.h"
    #include "MyPlayerController.generated.h"
    
    /**
     * 
     */
    
    DECLARE_DYNAMIC_MULTICAST_DELEGATE(FTestDelegate);
    
    UCLASS()
    class SOCKETTEST_API AMyPlayerController : public APlayerController
    {
    	GENERATED_UCLASS_BODY()
    	
    	
    public:
    	virtual void Tick(float DeltaTime) override;
    	virtual void BeginPlay() override;
    
            void TestFunction();
    
    	UPROPERTY(BlueprintAssignable, Category = "Test")
    		FTestDelegate OnTestDelegate;
    };
    Now you should have spotted the UPROPERTY at the bottom of my example.
    This is the part you add a Delegate (here called "OnTestDelegate").
    The UPROPERTY "BlueprintAssignable" give you the possibility to bind/assign
    this function to a custom event in your BP Child class.

    You should be able to bind a delegate in C++ AND Blueprint and call both
    bound functions/events through c++.

    Code:
    UPROPERTY(BlueprintAssignable, Category = "Test")
    	FTestDelegate OnTestDelegate;
    If you want to add a function to it, you need to call "AddDynamic" on the delegate.
    The editor won't show you this and maybe shows an error. Just try to compile anyway....

    Here is an example for the normal, non param delegate from above, inside your CPP File:

    Code:
    OnTestDelegate.AddDynamic(this, &AMyPlayerController::TestFunction);
    If you now want to call your delegate inside your code do this at the desired position:

    Code:
    OnTestDelegate.Broadcast();

    I hope this helps (:
    Why did you use
    Code:
    DECLARE_DYNAMIC_MULTICAST_DELEGATE
    over
    Code:
    DECLARE_EVENT
    ?

    DECLARE_DYNAMIC_MULTICAST_DELEGATE is very often used in the gameplay framework so I am wondering why I would use it instead of DECLARE_EVENT.

  6. #6
    0
    Hello,

    This is what worked

    Code:
    #include "Acpp_character.h" // to get the class declaration
    
    void Acpp_tennisBall::BeginPlay ()
    {
        Acpp_character *c =  Cast <Acpp_character>(GetWorld ()->GetFirstPlayerController ()->GetCharacter ());
        c->OnMoveToPosition.AddDynamic (this, &Acpp_tennisBall::MoveToPosition);
    }
    Is there a elegant way to do this via ConstructorHelpers. The Acpp_character object is instantiated only ingame through the custom GameMode's Default Pawn Class.
    Last edited by TheJamsh; 03-09-2016 at 05:23 PM. Reason: added code tags

  7. #7
    0
    Infiltrator
    Join Date
    May 2015
    Posts
    24
    Do I need to remove delegates (REmoveDynamic) when the actor is destroyed? How does that work with UE garbage collection management?

  8. #8
    0
    It is actually dynamic delegates. If you mark BlueprintAssignable it will appears as blueprints' eventdispatcher

  9. #9
    0
    I'm having trouble binding methods from other objects. Can someone help me?

  10. #10
    0
    Quote Originally Posted by yateam View Post
    Do I need to remove delegates (REmoveDynamic) when the actor is destroyed? How does that work with UE garbage collection management?
    The subscription to a delegate is a weak reference, so you don't have to worry about them keeping objects from being garbage collected.

  11. #11
    0
    Can someone show how is it done? Bind a Delegate of one Actor to another? I'm trying but the game keeps crashing. Can anyone supply a functional example code? Please?

  12. #12
    0
    Quote Originally Posted by LuLima View Post
    Can someone show how is it done? Bind a Delegate of one Actor to another? I'm trying but the game keeps crashing. Can anyone supply a functional example code? Please?
    Something like this:

    Code:
    void AMyActor::MyFunction(AActor* AnotherActor)
    {
       // When AnotherActor is destroyed, call this->HandleAnotherActorDestroyed()
       AnotherActor->OnDestroyed.AddDynamic(this, &AMyActor::MyHandle);
    }
    
    void AMyActor::HandleAnotherActorDestroyed()
    {
       // Do something here
    }

  13. #13
    0
    Quote Originally Posted by maikklein View Post
    Why did you use
    Code:
    DECLARE_DYNAMIC_MULTICAST_DELEGATE
    over
    Code:
    DECLARE_EVENT
    ?

    DECLARE_DYNAMIC_MULTICAST_DELEGATE is very often used in the gameplay framework so I am wondering why I would use it instead of DECLARE_EVENT.
    It's been a while since I did this, but both from my experience using the delegates and looking at their usage in the code base the big difference between DECLARE_EVENT and DECLARE_DYNAMIC_MULTICAST_DELEGATE is that dynamic delegates can be looked up by name and therefore can be used/exposed to blueprints. I don't think I've ever been able to use DECLARE_EVENT from a blueprint.

  14. #14
    0
    Quote Originally Posted by manoelneto View Post
    Something like this:

    Code:
    void AMyActor::MyFunction(AActor* AnotherActor)
    {
       // When AnotherActor is destroyed, call this->HandleAnotherActorDestroyed()
       AnotherActor->OnDestroyed.AddDynamic(this, &AMyActor::MyHandle);
    }
    
    void AMyActor::HandleAnotherActorDestroyed()
    {
       // Do something here
    }
    I tried something like this and it is crashing during gameplay. how to you define the delegate?

  15. #15
    0
    OnTestDelegate.Broadcast();
    -------------------------------------
    How could i do this in blueprint?

  16. #16
    0
    Infiltrator
    Join Date
    Apr 2016
    Posts
    12
    Name:  checkpoint.png
Views: 8056
Size:  280.4 KBName:  Tracker.png
Views: 8027
Size:  375.1 KB

    Hi !
    I not sure if this is the right place to ask this question, so please guide me if it is not.

    Current I am doing the "Time Attack Racer" example, I wrote the 'checkpoint' entirely in C++ while the other actors in blueprint (Cause I need the checkpoint to do other things for my project).But I am Stuck at the Event dispatcher, I tried the above ' event dispatch' method in my checkpoint and cannot bind it to 'Tracker' in the blueprint.
    Any Help is appreciated !
    Thank

    cheer
    YanJie
    Last edited by yanjieng; 07-03-2016 at 11:45 AM.

  17. #17
    0
    Quote Originally Posted by eXi View Post
    Code:
    #pragma once
    
    #include "GameFramework/PlayerController.h"
    #include "MyPlayerController.generated.h"
    
    /**
     * 
     */
    
    DECLARE_DYNAMIC_MULTICAST_DELEGATE(FTestDelegate);
    
    UCLASS()
    class SOCKETTEST_API AMyPlayerController : public APlayerController
    {
    	GENERATED_UCLASS_BODY()
    	
    	
    public:
    	virtual void Tick(float DeltaTime) override;
    	virtual void BeginPlay() override;
    
            void TestFunction();
    
    	UPROPERTY(BlueprintAssignable, Category = "Test")
    		FTestDelegate OnTestDelegate;
    };
    Hi, fairly new UE user here.
    I noticed making the delegate function private also works. Is there any reason for it to be public instead of private?

    Thanks!

  18. #18
    0
    Mythic






    Join Date
    Jul 2014
    Posts
    2,250
    Quote Originally Posted by bloodmeat10 View Post
    Hi, fairly new UE user here.
    I noticed making the delegate function private also works. Is there any reason for it to be public instead of private?

    Thanks!
    If it works with them being private, then no.
    Have you tested binding the Delegate in a different BP Class then "MyPlayerController"?
    Blueprint exposed UPROPERTY's always tell me they can't be private. So I thought protected and public is better here :x
    Open for contracted work | Blueprints | UE4++/C++ | Training | VR | My Website

    My UE4 Blog/Page with Free Learning Projects and more: Hit me for ALL the things!

    BP Multiplayer Lobby System: [Released] Support Thread! | BP Multiplayer Crafting System: [Released] Support Thread!

  19. #19
    0
    Quote Originally Posted by eXi View Post
    If it works with them being private, then no.
    Have you tested binding the Delegate in a different BP Class then "MyPlayerController"?
    Blueprint exposed UPROPERTY's always tell me they can't be private. So I thought protected and public is better here :x
    You can add "meta = (AllowPrivateAccess = true)" to the UPROPERTY macro on a private field, which explicitly gives Blueprint permission to read and write that field. For dynamic multicast delegates I prefer to keep the field private, apply AllowPrivateAccess, and provide a public read-only accessor to the delegate for C++ code to bind to it. That way users of your code can't accidentally overwrite the delegate with a different instance.

  20. #20
    0
    Very useful post here. Having just implemented a C++-declared Event Dispatcher per the above - a note, for full functionality you will want to add BlueprintCallable as well to allow your blueprint to call your event dispatcher:

    > UPROPERTY(BlueprintAssignable, BlueprintCallable, Category = "Test")
    > FTestDelegate OnTestDelegate;

  21. #21
    0
    The Rainbow Warrior



    Join Date
    Mar 2014
    Posts
    2,601

    Red face Wiki on Blueprint Events / C++ Delegates

    Dear Community,

    I have a wiki on this topic here:

    How to create Blueprint Events from C++ & C++ Delegates
    https://wiki.unrealengine.com/Delegates_In_UE4,_Raw_Cpp_and_BP_Exposed

    Excerpt:
    Level Blueprint Friendly Delegates

    When you've made BP-friendly delegates on objects that you can place in the level, you can simply right click on the object instance in your level -> Add Event and see your new delegate! So nice!

    This is an additional benefit of using DYNAMIC_MULTICAST delegates! Multi-cast implies binding multiple of various object instances to the delegate and then firing off the event to everyone from a single .Broadcast, which can include your Level Blueprint as a recipient/listener!



    Rama
    100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

    UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

    Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •