Override Actor Component functions in Owning Actor?

They can but the point here is I don’t want the actor or other components to necessarily have to know about all the functionality of other components - so interfaces are out of the question there.

Think of it like Particle Modules or Widgets - I want them to be able to interact with and talk to one another, without knowing exactly what each is doing. E.g, an ‘Ammo’ module and a ‘Firing’ module. The ‘Firing’ module would override ‘CanFire()’ in the Actor Blueprint, and check if the ‘Ammo’ module has enough ammo.

In the same way, a Widget can be added to a Widget Blueprint, and it’s properties can be adjusted in the main Widget Blueprint. You don’t have to create a new sub-class of a UCanvasPanel when you want to change the way it’s visibility is controlled.

I’ve been trying to extend the Blueprint Editor, with a drop-down menu of all overrideable functions in the actors’ components. Getting the list of those functions seems to be possible with some trickery, and under the hood it looks as though native functions are just re-routed to BP ones and serialized - but so far I’ve not been able to implement them since the Blueprint Editor is a pain in the *** to extend.

This is how I’m gathering the functions so far.



void FHT_ExtendedOverrideToolbar::GetModuleFunctions(const UBlueprint* Blueprint, TMap<UObjectProperty*, TArray<TSharedPtr<FEdGraphSchemaAction_K2Graph>>>& ComponentFunctionActionsMap)
{
    ComponentFunctionActionsMap.Reset();

    check(Blueprint);
    check(FBlueprintEditorUtils::DoesSupportEventGraphs(Blueprint));

    // Need this for some reason...
    const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();

    // Find all UObjectProperty Pointers on the Actor Class
    UClass* ParentClass = Blueprint->SkeletonGeneratedClass ? Blueprint->SkeletonGeneratedClass->GetSuperClass() : *Blueprint->ParentClass;
    for (TFieldIterator<UObjectProperty> PropertyItr(ParentClass, EFieldIteratorFlags::IncludeSuper); PropertyItr; ++PropertyItr)
    {
        const UObjectProperty* Property = *PropertyItr;
        const FName PropertyName = Property->GetFName();
        const UClass* PropClass = Property->PropertyClass;

        // Find all Override-able UFunctions in the Weapon Module
        if (PropClass && PropClass->IsChildOf(UHT_WeaponModule::StaticClass()))
        {
            for (TFieldIterator<UFunction> FunctionItr(PropClass, EFieldIteratorFlags::IncludeSuper); FunctionItr; ++FunctionItr)
            {
                const UFunction* Function = *FunctionItr;
                const FName FunctionName = Function->GetFName();

                // Check if we can override this function
                if (UEdGraphSchema_K2::CanKismetOverrideFunction(Function) && !FObjectEditorUtils::IsFunctionHiddenFromClass(Function, PropClass))
                {
                    const FText FunctionTooltip = FText::FromString(UK2Node_CallFunction::GetDefaultTooltipForFunction(Function));
                    FText FunctionDesc = K2Schema->GetFriendlySignatureName(Function);
                    if (FunctionDesc.IsEmpty())
                    {
                        FunctionDesc = FText::FromString(Function->GetName());
                    }

                    FText FunctionCategory = Function->GetMetaDataText(FBlueprintMetadata::MD_FunctionCategory, TEXT("UObjectCategory"), Function->GetFullGroupName(false));

                    TSharedPtr<FEdGraphSchemaAction_K2Graph> NewFuncAction = MakeShareable(new FEdGraphSchemaAction_K2Graph(EEdGraphSchemaAction_K2Graph::Function, FunctionCategory, FunctionDesc, FunctionTooltip, 1, NodeSectionID::FUNCTION_OVERRIDABLE));
                    NewFuncAction->FuncName = FunctionName;

                    // Add Items
                    ComponentFunctionActionsMap.FindOrAdd(Property).Add(NewFuncAction);
                }
            }
        }
    }
}