Recently I got bored and decided to add Discord Rich Presence to the Unreal Editor. As part of this, I needed a way to fire off a callback as often as possible, this is usually done every frame. For games, you'd place the code within an Actor and use its built-in Tick method. Unfortunately, Editor Modules, being Editor Modules, don't have Tick events as they aren't actual objects, they're just extensions of the Editor.
So how do we achieve this?
It's pretty simple, actually. It relies on the Ticker class. To use is we just need to include a single header in your .cpp file:
Ticker is built into Unreal, you shouldn't need any other modules or dependencies.
Then we want to set up the Delegate and Handle by adding:
Essentially the Delegate work's how Delegates usually work with any language, you bind it to a function and it runs the bound function whenever the delegate is called. Handles tend to act as extra configuration for the Delegate. If you've used a Timer in Blueprints you should have an understanding of how Delegates and Handles work in a more visual way.
So this is pretty self-explanatory. First, we are using CreateRaw to create the delegate binding. This passes in our Tick function, which we will create in a moment. Or you could create it now, it's not that difficult. You then set up the Handle by directly calling the FTicker class and adding the Delegate as a Ticker. This creates the Handle.
This is pretty self-explanatory too. We get DeltaTime from the Tick. I haven't done rigorous testing but, from what I can tell, it must return true. I assume this tells the Ticker that the tick was successful and allows it to run again.
And, finally, this is an important one. When your module shuts down, we want to run RemoveTicker on the Handle. As my Discord plugin runs as an Editor module, I want to make sure everything has cleared and shutdown cleanly. Unreal can sometimes leave a background process running so it's better to clean house as much as possible.
I will be releasing a guide on creating the Discord Editor plugin soon™.