How to access the UE4 Editor Clock/Ticking System for use in a Plugin

Hi,
I am creating a plugin where I need to access the clock or a ticking system for the editor rather than the game. Is there a way I could bind to the editor’s clock, ticking system, or event scheduler to run a callback every n seconds or every frame?

Thank you.

try to see if GetWorld() is valid at editor time!

Thank you, however I am in need of an editor singleton getter, rather than a world getter.

Editor also has its own World.

If you want to hook into it from a plugin, you can do something like this in StartupModule :

auto delegate = FWorldDelegates::FWorldInitializationEvent::FDelegate::CreateRaw(this, &FMyPlugin::OnPostWorldInitialization);
FWorldDelegates::OnPostWorldInitialization.Add(delegate);

With callback like this :

void FMyPlugin::OnPostWorldInitialization(UWorld* World, const UWorld::InitializationValues IVS)
{
    if (World)
    {
	    // World->GetTimerManager
        // or
        // World->SpawnActor
    }
}

Note that editor spawns multiple worlds, so you may want to add some checks if you only want to use a specific one, like World->IsEditorWorld() or World->IsPlayInEditor() or World->IsGameWorld().

I’d suggest spawning an Actor into the world to use timer or tick, rather than trying to bind the timer manager to a plugin function.

Thank you. However, I am getting a “Cannot open include file: ‘Engine/World.h’: No such file or directory” error when I go to compile. However, Intellisense reconizes the .h file and no longer errors out the FWorldDelegates. Any ideas on what might be occurring?

Make sure you include “Engine” in your Build.cs file

Thank you! The callback occurred twice even with a condition on “IsEditorWorld()”. There seems to be two calls to the FWorldDelegates::OnPostWorldInitialization that pass “IsEditorWorld()”. How might I condition, so there is only one?

Well I don’t know exactly as I’ve never used it in that specific way, but you can debug it out by printing World->GetName() for example. I suspect it might work like the normal game and load a world for each map. If that’s the case, you’ll want to spawn the actor in each of them. Also mark your actor RF_Transient so it doesn’t get saved into maps.

Another option would be to spawn an UObject rather than an actor. Just store it in a UObject* variable, and add it to the root set so it doesn’t get garbage collected. Implementing the FTickableGameObject should make your object tick like an actor, and it should be world-independent. Declaration should look somewhat like this

UCLASS()
class UMyObject : public UObject, public FTickableGameObject
{
	GENERATED_BODY()
public:
	// FTickableGameObject interface
	virtual void Tick(float DeltaTime) override;
	virtual TStatId GetStatId() const override { RETURN_QUICK_DECLARE_CYCLE_STAT(UMyObject, STATGROUP_Tickables); }
	virtual bool IsTickable() const override { return true; }
	virtual bool IsTickableWhenPaused() const override { return true; }
};

Then you can create your object directly in StartupModule and don’t even need to mess with worlds

MyObject = NewObject<UMyObject>();
MyObject->SetFlags(RF_MarkAsRootSet);