Is there a way to call a function when an actor is placed in the editor?

Hello, i have a small problem with placing actors in the editor and getting a function called on them.
What i want is that when the actor is dragged out from the content browser and then placed in the world a function should be called to set some default values.

From what i have tested i can probably get the OnConstruction() function to do what i want.
I have the function set up like this.

void APhysicsActor::OnConstruction(const FTransform& Transform)
{
	Super::OnConstruction(Transform);

	if (!HasDoneFirstConstruct && GetWorld()->WorldType == EWorldType::Editor)
	{
		UE_LOG(LGeneral, Warning, TEXT("OnConstruction: %s, %s"), *GetName(), *Transform.ToString());
        SetupDefaults();
		HasDoneFirstConstruct = true;
	}
}

What happens with this function is that the function is called twice, once when the actor is dragged into the editor viewport and then once more when the mouse is released and the actor is placed into the world.
Is there some way to fix so that it is only called once, when the actor is placed in the world?

Or is there some other way to achieve the results i want?

Thanks!

It’s 5 years later, but someone else might stumble across this like I did.
I used a similar method to yours, but I used the PostEditMove( ) function, which is an editor function. I don’t know that there’s a function specifically called when placing an actor in the editor, however any time you move it even a tiny amount, such as when you place it in the level, this editor function gets called. Likewise, I used a flag in my actor class to make sure what I want to happen only happens the first time it gets placed/moved in the level.

As with all editor functions, make sure both the declaration and implementation are wrapped around #if WITH_EDITOR.

#if WITH_EDITOR
	virtual void PostEditMove(bool bFinished) override;
#endif

#if WITH_EDITOR
void AMyActor::PostEditMove(bool bFinished)
{
	// Only call this a single time when an actor is first placed (moved) in a level
	if (false == PostEditMoveHasBeenCalled)
	{
		// The stuff you want to do when you place an actor in the level goes here

		PostEditMoveHasBeenCalled = true;
	}
	Super::PostEditMove(bFinished);
}
#endif
1 Like