Is it possible to have a construction script for Actor components? I am currently using the Actor Component to add additional functionality to existing actors, such as physics impact sounds, footstep sounds, flickering lights etc.
It is possible to use the BeginPay event to do some initial setup, however this could be costly when starting the game if the component is doing a lot of computation, or you have a bunch of actors using the Actor Component.
##Example
A flickering component that has to initially loop through components in the parent actor and create an array of light components, and create dynamic emissive material instances to be modified on the Tick event in response to a linear color curve.
At the moment, no. But what you can do is make your component an actor instead and attach that as additional functionality to existing actors. It works but with that said, I’d prefer a construction script within the actor components.
Only OnConstruction method of AActor is virtual, but blueprint logics happened in UserConstructionScript which we can’t override in child class.
It works, but causes bugs and gives engine displeasure if ActorComponent “Construction Script” will add another components to actor…
“Ensure condition failure” about changed components count in actor construction logics.
Placed on scene this actor will snaps to zero coordinates.
Creates two copies of component in actor (how second copy appeared I didn’t figured out, and one of copy will be also snapped to zero coordinates and can’t be moved with actor)
It’s 2023 now I assume there’s no progress? Would be nice to inject logic into the GameState through components, if the components do initialization on a construction script…
By default Unreal prevent blueprint scripts to run on editor. You nedd to add a FEditorScriptExecutionGuard at the scope that is calling the BlueprintImplementableEvent to enable script calls during editor run.
I added the required line surrounded by comments in the code below.
UCLASS(BlueprintType, Blueprintable)
class MY_API AExtActor : public AActor
{
GENERATED_BODY()
public:
virtual void OnConstruction(const FTransform& Transform) override
{
for (UActorComponent* Component : GetComponents())
{
if (UExtActorComponent * ExtComp = Cast<UExtActorComponent>(Component))
{
ExtComp->ProcessConstructionScript(Transform);
}
}
}
};
UCLASS(BlueprintType, Blueprintable)
class MY_API UExtActorComponent : public UActorComponent
{
GENERATED_BODY()
public:
void ProcessConstructionScript(const FTransform& Transform)
{
/////////// Just add this line /////////////
FEditorScriptExecutionGuard ScriptGuard
////////////////////////////////////////////
OnConstruction(Transform);
ConstructionScript();
}
virtual void OnConstruction(const FTransform& Transform) {};
UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Construction Script"))
void ConstructionScript();
};
They don’t run construction scripts. Granted, I haven’t tested this in a couple of years to see if Epic fixed it, but I’ve learned to not get my hopes up…
Personally, to have the equivalent of a ConstructScript able to perform operations on the parent (or another component) and also be executed in the editor, I use the OnRegister() function.
What do I actually do?
In C++, I create a class inheriting from ActorComponent, which we call AC_Base. This class is Blueprintable.
I declare an OnThisRegister() function which is BlueprintImplementableEvent.
I override OnRegister() so that it calls my OnThisRegister() method.
I inherit my next (Blueprint) actor components from AC_Base.
I implement the event OnThisRegister() in the Blueprints.
I’ll leave you with the header and source code for AC_Base.