Skip to content

Instantly share code, notes, and snippets.

@aquanox
Last active April 14, 2025 08:34
Show Gist options
  • Select an option

  • Save aquanox/f4fbbed45545a3206179d0ddede40ed1 to your computer and use it in GitHub Desktop.

Select an option

Save aquanox/f4fbbed45545a3206179d0ddede40ed1 to your computer and use it in GitHub Desktop.
Smart Default Event Nodes
// Normally it is possible to register each member function to be spawned as default like this
// But it does not work with ForceAsFunction or BlueprintNativeEvents that return value that spawn function graphs
// FKismetEditorUtilities::RegisterAutoGeneratedDefaultEvent(this, UDynamicAssetFilter::StaticClass(), GET_FUNCTION_NAME_CHECKED(UDynamicAssetFilter, K2_FilterAsset));
//
// By utilizig RegisterOnBlueprintCreatedCallback can track new blueprint creation and do any stuff to blueprints
// for example - finding BlueprintDefaultEvent meta and creating default node or graph for Blueprint(Native|Implementable)Event
// With this hook any BNE/BIE with BlueprintDefaultEvent will be generated into default node or overridden by default function
// No more need to manually register each function
void MODULENAME::RegisterBlueprintDefaultEvents()
{
IModuleInterface* ModuleThis = this;
FKismetEditorUtilities::RegisterOnBlueprintCreatedCallback(ModuleThis, UObject::StaticClass(), FKismetEditorUtilities::FOnBlueprintCreated::CreateLambda([ModuleThis](UBlueprint* InBlueprint)
{
UEdGraph* EventGraph = FBlueprintEditorUtils::FindEventGraph(InBlueprint);
// not all blueprints have graphs, also user may have it disabled
if (!EventGraph || !GetDefault<UBlueprintEditorSettings>()->bSpawnDefaultBlueprintNodes) return;
int32 NodePositionY = 0;
TArray<FName> AutoSpawnedEventNames;
for (TFieldIterator<UFunction> It(InBlueprint->GeneratedClass, EFieldIterationFlags::IncludeSuper|EFieldIterationFlags::IncludeInterfaces); It; ++It)
{
FName EventName = It->GetFName();
if (It->HasAllFunctionFlags(FUNC_Event|FUNC_BlueprintEvent) && It->FindMetaData(TEXT("BlueprintDefaultEvent"))
&& !InBlueprint->GeneratedClass->IsFunctionImplementedInScript(EventName) && !AutoSpawnedEventNames.Contains(EventName))
{
AutoSpawnedEventNames.Add(EventName);
UFunction* OverrideFunc = nullptr;
UClass* const OverrideFuncClass = FBlueprintEditorUtils::GetOverrideFunctionClass(InBlueprint, EventName, &OverrideFunc);
check(OverrideFunc);
if (UEdGraphSchema_K2::FunctionCanBePlacedAsEvent(OverrideFunc))
{ // Create new red event node
FKismetEditorUtilities::AddDefaultEventNode(InBlueprint, EventGraph, OverrideFunc->GetFName(), OverrideFuncClass, NodePositionY);
}
else
{ // Create new function graph
UEdGraph* const NewGraph = FBlueprintEditorUtils::CreateNewGraph(InBlueprint, OverrideFunc->GetFName(), UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
FBlueprintEditorUtils::AddFunctionGraph(InBlueprint, NewGraph, /*bIsUserCreated=*/ false, OverrideFuncClass);
NewGraph->Modify();
}
}
}
}));
}
void MODULENAME::UnRegisterBlueprintDefaultEvents()
{
FKismetEditorUtilities::UnregisterAutoBlueprintNodeCreation(this);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment