Announcement

Collapse
No announcement yet.

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

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    Yes you can, with delegates.

    https://docs.unrealengine.com/latest...tes/index.html

    Comment


    • #3
      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, 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!

      Comment


      • #4
        Hello,

        New to UE4 c++ API.

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

        Thank you,
        Nihal Kenkre.

        Comment


        • #5
          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.

          Comment


          • #6
            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, 05:23 PM. Reason: added code tags

            Comment


            • #7
              Do I need to remove delegates (REmoveDynamic) when the actor is destroyed? How does that work with UE garbage collection management?

              Comment


              • #8
                It is actually dynamic delegates. If you mark BlueprintAssignable it will appears as blueprints' eventdispatcher
                My Github: https://github.com/henrya2

                Comment


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

                  Comment


                  • #10
                    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.

                    Comment


                    • #11
                      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?

                      Comment


                      • #12
                        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
                        }

                        Comment


                        • #13
                          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.
                          VR R&D @Shopify

                          Comment


                          • #14
                            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?

                            Comment


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

                              Comment

                              Working...
                              X