You don’t need any switch but you do need an interface.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "HitInterface.generated.h"
UINTERFACE(NotBlueprintable)
class UHitInterface : public UInterface {
GENERATED_BODY()
};
class IHitInterface {
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, BlueprintPure = false)
virtual void OnHit() = 0;
};
#pragma once
#include "CoreMinimal.h"
#include "MyCar.generated.h"
UCLASS()
class UMyCar : public UObject, public IHitInterface {
GENERATED_BODY()
public:
virtual void OnHit() override;
};
This ensures the implementation of what happens on “hit” is written in the classes themselves, not switched on some kind of manager. Whenever you feel like you need a switch or casts (if many) you want to move logic into separate classes, or component. Components can have interfaces too. Then you’d get the component by class (no need for any tags as well), call the interface on it.
Yes I did assume this is more logical based on what I see on the use case image.
*Edit * If you do go the “call by name” route, then →
There are downsides to calling a function name by FName. If you were to change your function name at any point any stored function FName will not change and will not notify you that they will not work anymore.
In C++ I can give an example how to pass around UFunction a safe way, that if the name were changed the code would not compile:
It’s quite critical to get such functionality right, wouldn’t try to do this in blueprints in the first place, risking FNames going outdated just anywhere.
I’m mostly seeing cons especially on the blueprint side, and especially if you store the function names up front.
blueprint nodes, compiling, etc won’t notify when FNames don’t match a function name.
chance of typing mistakes, outdated data, clearing data without notifications.
redirectors will not work.
Not seeing the pros yet my example where I pass along a function pointer was for a specific use case where I want to bind a function on a delegate along with other data.
UFUNCTION(BlueprintCallable,meta = (DefaultToSelf = "Object"))
static bool CallFunctionByName(UObject* Object, FName FunctionName)
{
if (Object)
{
if (UFunction* Function = Object->FindFunction(FunctionName))
{
Object->ProcessEvent(Function, nullptr); return true;
}
else
{
UE_LOG(LogTemp,Warning,TEXT("Trying to run function named %s but is not found"), *FunctionName.ToString() );
return false;
}
} return false;
}
now it notifies if function is not found also the node returns a success bool
I know a lot of people dont recommend using BP nodes like ‘set timer by function name’ as it is error prone and this call function by name can be too but idk…I like it and who doesnt just dont use. Its just a feature.
I made adjustments to a function that I was calling using “Set Timer By Function Name” The function was called BP_SelectActors. I did not notice at some point it changed the name ti BP Select Actors. I thought I had done something in the function to break it. I ended up rolling back to an earlier commit and it still didn’t work. I then noticed the function name had changed.
I switched it to “Set Timer by Event” and pull off from event and 'Create Event". The pull down has a list off all functions in the blue print and will update if the name changes.
it doesn’t work if called from c++ static context didn’t try to call from object. I’m passing arguments instead of nullptr to as *void as well. Works if called from blueprints.
My problem was I tried to call bp function on editor time but function wasn’t flagged as editor function, once I flagged it everything worked fine and even *void argument passed as struct reference was properly read.