How to implement Events strictly on C++ side?

Hello,

I’ve been transforming my blueprint implemented game prototype to a strict C++ implementation because of several important reasons.

But I am confused about how I could implement Unreal events in C++ with calls to latent methods like Delay()…

From what I understand Functions and Events are very different concepts in Unreal.

Events are basically threads which does not have a return value and can execute latent functions like delay.

Functions on the other hand does not fork like events and continue executing on the main thread of the caller.

This I’ve figured out… However I am really confused about how to implement events which can call latent functions like delay not on Blueprint editor but on C++ side…

I have the below two questions:

  1. The UFUNCTION() macro has two relevant specifiers called BlueprintNativeEvent and BlueprintImplementableEvent. First one lets us give an implementation of the method in C++. The second lets the blueprints do it. I’ve noticed that you could assign return values to the methods you define with these specifiers on C++ side. But then the names become misleading. They both have the “Event” in the specifier name though they can be used to write functions. Can BlueprintNativeEvent and BlueprintImplementable event be used to implement Events but not Functions? Are there any additional specifiers to mark a method as an event/thread but not a function? Can I for instance call a latent method inside a method which has the BlueprintNativeEvent property? Can they act as threads in some way? Do they automatically become events/threads if I dont specify a return type?

  2. I’ve also noticed that there is the Event type delegate mechanism, in which you can specify a delegate to an event.

To implement Events strictly on C++ which one is the correct way to go?

I am totally confused about this issue and I will appreciate any help I could get.

I would like to clarify my question with an example…

I would like to implement a damage effect on the player. Whenever the player takes damage the camera should fade in to red, delay a little bit and do some computations there and fade out again. This is very easy to do in blueprint editor (just a single event which contains 3-4 nodes some of which are latent)

But on C++ side how can this be achieved? There are a number of answers in the forum which suggests to use timers instead of calling latent functions from the C++ side. But this will be very cumbersome. Such an approach requires me to break the function into three separate functions and link these functions to the timer events each. So for each latent call I would require a new function even if I use the same timer. This would populate my classes with a lot of functions for each latent process similar to the example above… and would make things really hard to manage.

If I can declare the method that will be used by an event/thread on C++ side and if I make sure that it is a separate thread (not the main thread) calling it, I feel that it should be possible to achieve this on C++ side.

Could this be achieved?

If so how should this be implemented on C++? With a BlueprintNativeEvent function with no return type? Or perhaps an Event delegate bound to a UFUNCTION in C++.

Thanks again for answers…

Since there are no answers to this question yet I’ve decided to write a TestActor which tests if BlueprintNativeEvents (or in general blueprint events) act as threads or not.

My findings are very strange…

Here is the header for the actor:

120047-testactorheader.png

And the implementation:

The basic idea is to see if the call to NativeFooWithoutReturn() method blocks the execution at beginPlay (and hence also the game). I calculated the time difference to see how long this block takes place.

In NativeFooWithoutReturn_Implementation() I’ve tried several things…

  1. I’ve put a very long for loop (like 999999999). And it blocks the game and the editor entirely for a short time so it seems NativeFooWithoutReturn runs on the main execution thread not a separate thread once called in BeginPlay.

  2. I’ve replaced the loop via FProcess::Sleep()… the same naturally occured.

In the second trial I’ve tried to implement (override) the NativeFooWithoutReturn in BlueprintEditor. I’ve derived a new class from TestActor and implemented the NativeFooWithoutReturn like this:

Surprisingly this case also blocked the game and the editor. So that means the NativeFooWithoutReturn event is not a separate thread but still running on the main execution thread.

I want to make an off topic note here as well. The BeginPlay() method on C++ side reported around 2 seconds of delay in this case. However the same code for the C++ only implementation of the NativeFooWithoutReturn function is handled in less than 0.01 seconds. That means around 200 times slow down for the editor compared to pure C++ implementation (one more reason to go for C++).

Now here comes the case which will blow your mind off! :smiley:

I’ve added a latent delay node to the Editor implementation. And Kaboom! suddenly NativeFooWithoutReturn() becomes a thread. The C++ BeginPlay() reports 0 second delay and the game does not freeze. Also the ordering of the log messages change in this case as BeginPlay() on C++ prints both the messages and exits right away…

So the result of this trial is that Blueprint Events are not separate threads. They do execute on the main execution thread unless you put some latent nodes (with clock sign on top-right corner) to it (like Delay, Camera Fade methods etc.)

As a side note I’ve also tried to declare a delegate (tried multi-cast, single-cast, event etc) called FooEvent and bound a FooFunction to it in BeginPlay(). Then I called fooEvent.Broadcast() in place of NativeFooWithoutReturn(). The FooFunction has the exact same implementation as NativeFooWithoutReturn_Implementation()…

The result is the same as above and the delegate function call also blocked the game and the editor together. That means even if you use function delegates all execution is still handled within a single master execution thread by Unreal Engine.

So it seems the only way to solve my original problem is to implement a thread mechanism by myself or to use timers etc.

Therefore I answered my own question.

But I would still appreciate any comments or insights about this issue…

Thanks a lot about this Issue ! I just want to know about how to implemente “delay” while you let me have a deep thought about threads and Event functions.It help me a lot!
I appreciate if you get some new solutions of this issue.About threads or Event etc…
I am Chinese and myEnglish is not very good.So is there any mistakes of my words ,please forgive me. Thank you!

So what is your solution about your issue. Are you really create a seperate thread by youself?

whats more,Some fimiliar nodes like “tImeline” even “sequencer” are also relavant with this issue(the thread).So I hope your new opinions about these issue.

I dont think this experiement proves that you are running in a new thread.

I think that your code runs till it hits the delay then everything after the delay is scheduled to run later and OnBeginPlay continues on.
This does not mean it is running on a different tread it is probable that it is running on the game thread but it is running later when the timer runs out.
The way to test this would be to check if there is a frame drop when the delay finishes.