CallFunctionByNameWithArguments not working

Hey there,

I got a weird problem where

CallFunctionByNameWithArguments

returns true but the call is not reaching the Actor. I’m currently writing an EditorMode Plugin and I scan a selected Actor for all its EXEC functions. That seems to work and the Actor as well as the Function name are correct.
I can even call the Function directly on the Actor (if I cast it). The “CallFunctionByNameWithArguments” event returns false if something doesn’t work. I followed the execution line a while but I lost track in during the “ProcessEvent” function, cause it simply calls the Super of that and that’s it.

I tried writing the name directly into the function, right and wrong, and it failed with the wrong name and returns true with the correct name.

The whole thing is called by a button press in the Editor:

FReply STrafficDetailsWidget::ExecuteToolCommand(UFunction* MethodToExecute)
{
	UE_LOG(LogTemp, Warning, TEXT("Trying to Execute Command!"));

	if (GEditor && GEditor->GetSelectedActorCount() > 0)
	{
		USelection* SelectedActors = GEditor->GetSelectedActors();

		UObject* LastActor = SelectedActors->GetSelectedObject(GEditor->GetSelectedActorCount() - 1);

		if (LastActor)
		{
			AStreetNode* TestActor = Cast<AStreetNode>(LastActor);
			if (LastActor->CallFunctionByNameWithArguments(*FString("TestFunction"), *GLog, nullptr, true))
			{
				//TestActor->TestFunction();
				UE_LOG(LogTemp, Warning, TEXT("Called Function"));
			}
			else
			{
				UE_LOG(LogTemp, Warning, TEXT("Something went wrong"));
			}
		}
	}

	return FReply::Handled();
}

Does anyone have an idea why the function returns TRUE but the actual function i want to call never gets called?

Michael Noland gave me the answer via Twitter. Would have never found that on my own so thank him if possible!

One needs to make sure “GAllowActorScriptExecutionInEditor” is TRUE. And that’s done by, for example, declaring “FEditorScriptExecutionGuard” before calling the function.

So the correct code now is:

FReply STrafficDetailsWidget::ExecuteToolCommand(UFunction* MethodToExecute)
{
	if (GEditor && GEditor->GetSelectedActorCount() > 0)
	{
		USelection* SelectedActors = GEditor->GetSelectedActors();

		UObject* ClickedObject = SelectedActors->GetSelectedObject(GEditor->GetSelectedActorCount() - 1);

		if (ClickedObject)
		{
			FEditorScriptExecutionGuard ScriptGuard;

			FOutputDeviceNull ar;
			ClickedObject->CallFunctionByNameWithArguments(*MethodToExecute->GetName(), ar, NULL, true);
		}
	}

	return FReply::Handled();
}
1 Like