Editor Crash for BluePrintImplementableEvent

I currently have a UClasswhich has two functions, DoAction and ActionTick, both of which are BlueprintImplementableEvents.

UCLASS(Blueprintable)
class MY_API UAction : public UObject
{
	GENERATED_BODY()
	
public:	

	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Execute"))
	void DoAction(AAgent* ActingAgent, AMyGameMode* CurrentGameMode);
	
	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Tick"))
	void ActionTick(AAgent* ActingAgent, AMyGameMode* CurrentGameMode, float DeltaTime);
};

An agent starts with a default UAction. This is just the C++ class, and not a blueprint class.

UAction* CurrentAction = NewObject<UAction>();

When ActionTick is called on CurrentAction the editor crashes with an access violation.

CurrentAction->ActionTick(this, static_cast<AMyGameMode*>(GetWorld()->GetAuthGameMode()), DeltaTime);

When debugging the violation occurs in UE4Editor-CoreUObject.dll!UClass::FindFunctionByName(FName InName, EIncludeSuperFlag::Type IncludeSuper) Line 4095 C++

If I try to step into that line I get the access violation. In the debugger InName is set to “Variable is optimized away and not available.”

I’m currently testing to see if I can set a default blueprint instead of c++ class.

Try adding these underneath your funtions

void DoAction_Implementation(AAgent* ActingAgent, AMyGameMode* CurrentGameMode);

void ActionTick_Implementation(AAgent* ActingAgent, AMyGameMode* CurrentGameMode, float DeltaTime);

Still seeing the same issue. Thanks for the suggestion though.

I was able to work around this by setting a default blueprint.

Instead of

UAction* CurrentAction = NewObject();

I now have

UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<UAction> DefaultAction;
UAction* CurrentAction;

And added this to my BeginPlay()

this->CurrentAction = static_cast<UAction*>(DefaultAction->GetDefaultObject());

What’s curious is that if I pass in UAction as the DefaultAction this still works.

Interestingly I was able to also just use the following:

UAction* CurrentAction = static_cast<UAction*>(NewObject<UAction>()->GetClass()->GetDefaultObject());

in place of

UAction* CurrentAction = NewObject<UAction>();

and it worked just fine.