Hey there, since 4.17 and the introduction of the BlueprintCompilationManager, Custom compilers for blueprints no longer work.
Normally, one could create a blueprint compiler and register it like this.
// Register the compiler for the ZD AnimBP
IKismetCompilerInterface& KismetCompilerModule = FModuleManager::LoadModuleChecked<IKismetCompilerInterface>("KismetCompiler");
KismetCompilerModule.GetCompilers().Add(this);
IKismetCompilerInterface having the interface calls for CanCompile, PreCompile, PostCompile and Compile among others.
This is good design, and lets users create custom compilers as I created with the PaperZD blueprint compiler.
The problem is that with BlueprintCompilationManager, this is replaced with a more… forced (or straight hardcoded) solution.
The struct FCompilerData holds the compiler that will be used but it uses this method to get which compiler context will be used (not IKismetCompilerInterface)
TSharedPtr<FKismetCompilerContext> FKismetCompilerContext::GetCompilerForBP(UBlueprint* BP, FCompilerResultsLog& InMessageLog, const FKismetCompilerOptions& InCompileOptions)
{
if(UAnimBlueprint* AnimBP = Cast<UAnimBlueprint>(BP))
{
return TSharedPtr<FKismetCompilerContext>(new FAnimBlueprintCompiler(AnimBP, InMessageLog, InCompileOptions, nullptr));
}
else
{
return TSharedPtr<FKismetCompilerContext>(new FKismetCompilerContext(BP, InMessageLog, InCompileOptions, nullptr));
}
}
As you can see, this makes it totally imposible to use the extended compiler context, making the “Compilers” array useless unless the CompilationManager is turned off.
Now, i understand that this is working deep on the engine, but the solution presented makes it totally imposible to use custom blueprints that can be compiled differently…
Is there something that can be done with this, patches can be created to bypass this or use the BlueprintPreCompile/PostCompile events to try to prepare the compilation and run the CustomKismetCompiler so as to “simulate” old behaviour, but the old solution was better in terms of flexibility
EDIT:
If this could be disabled “per” blueprint type, so as to support BlueprintCompilationManager on some blueprints but not on those who require full compile or custom compiling, the solution would be great and complete. Changing the code from Kismet2.cpp from
void FKismetEditorUtilities::CompileBlueprint(UBlueprint* BlueprintObj, EBlueprintCompileOptions CompileFlags, FCompilerResultsLog* pResults)
{
if(GBlueprintUseCompilationManager)
{
FBlueprintCompilationManager::CompileSynchronously(FBPCompileRequest(BlueprintObj, CompileFlags, pResults));
return;
}
....
To something like this:
void FKismetEditorUtilities::CompileBlueprint(UBlueprint* BlueprintObj, EBlueprintCompileOptions CompileFlags, FCompilerResultsLog* pResults)
{
if(GBlueprintUseCompilationManager && BlueprintObj->SupportsCompilationManager())
{
FBlueprintCompilationManager::CompileSynchronously(FBPCompileRequest(BlueprintObj, CompileFlags, pResults));
return;
}
....
Making the function call BlueprintObj->SupportsCompilationManager(), something that base classes can opt to override and make it return false if they need Full Compile for plugins, etc