How to do create component similar to 'Add __ Component' with a class type as an input?

I’m trying to replicate the functionality of the Blueprint nodes that create components. For example, if you are in an Actor Blueprint and you right click and search for ‘Add Sphere Collision’ it gives you a node that creates a new sphere collision component and attaches to the ‘Target’ actor. When you click on the node and look in the details panel you can even see all of the public properties like ‘Sphere Radius’. This even works for custom ActorComponent subclass BPs.

This is awesome but I need to be able to create a component without automatically attaching/registering it.

What I’m trying to do is have ActorComponents that serve as a sort of ‘status effect’, for example, a poison or burning damage over time thing which is attached to an actor, damages them ever x seconds and then destroys itself after the duration is up.

I’d like to be able to do is create the status effect component, pass it to my character, and let the character decide whether to apply it or reject it, etc. Like if you are immune to a certain effect or maybe some effects don’t stack so you want to make sure there’s only 1 of that type.

It seems like there’s no way to do this in BP so how can I create some helper functions or something that are exposed to BP?

The best I can get so far is to create and attach a component by a class type but you can’t choose any of the public properties which would be cool and again I can create a component but I don’t know how to attach/register it after the fact.

.h

UCLASS()
class BRIEF_FOXTAIL_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

	UFUNCTION(BlueprintCallable, Category = "MyBPLibrary")
	static void AddComponent(AActor* Owner, TSubclassOf<class UActorComponent> ComponentClass);
};

.cpp

void UMyBlueprintFunctionLibrary::AddComponent(AActor* Owner, TSubclassOf<UActorComponent> ComponentClass)
{
	if (Owner)
	{
		UActorComponent* NewComp = NewObject<UActorComponent>(Owner, ComponentClass);
		NewComp->bAutoActivate = true;
		NewComp->RegisterComponent();
	}
}

You can set any of the NewComp properties after you register it (NewComp->RegisterComponent).but you will have to pass them to AddComponent() function.

You can check this out: Unreal Engine 4 C++ Tutorial: Add Component - YouTube
It might give you some insight although it is not exactly what you want.

One question: If the character decides how to handle the component what functionality remains in that component class itself (other than data)? Wouldn’t it be better to pass a struct of some type with the desired values and have a component in the character which decides what to do with it?

The effect itself, once added and activated, would be responsible for registering any timers and events needed and can have it’s own functions,etc, and would do things to the owning Actor (of my custom Character class), like apply damage or change properties or call other functions, etc. And it would destroy itself after it expired. So it’s all encapsulated.

Where I wanted more control is being able to pass in a component to the character but give it a chance to decide to activate it or reject it, or remove an existing version of the same effect before adding the new one if it’s something not meant to stack multiple times. Like say if you get hit by a burning effect twice it just refreshes the duration of the effect rather than 2 separate instances doing their own damage; vs a slow effect that slows you by +10% per stack, so you can hit by a ‘slow’ spell multiple times in a row and the slow keeps adding up.

Honestly how I design it is really down to my requirements but I’m still prototyping so I’m not sure what those requirements are yet.

Now I have been thinking of just having 1 StatusEffectsManager component and passing around effects as structs? Still a bit hard to see how it will all come together but I will think more on that tomorrow.

Try passing the desired values to the function and applying them after registering/creation. Do tell if it works.


I am not trying to change your design. You might have good reasons to go through with this architecture. The reasons I asked the question are:

  1. If you set properties on different component classes on creation you would either need to have the same interface on all component classes, make logic to separate between them or outright create different AddComponent() functions like AddDamageOverTimeComponent().

  2. On the other hand these components would have to interact with whatever you slap them on so they would need to have some* knowledge about their parent’s interface like properties and functions they might need to modify or call.

  3. The character itself would need to have logic to distinguish between different component classes as it would need to modify the received properties (damage reduction) or outright discard the component. You would probably end up doing this in a StatusEffectManger component in the character anyway.

  4. Going “over the top” with creating and destroying components might lead to some noticeable hiccups as memory management is quite heavy on the CPU and (oh well…) memory side. Most notably unnecessary seems to me the creation and registration of a component just to be discarded or/and destroyed by the character it is created for.

(when I talk about interfaces I don’t necessary mean the Unreal interface class just the underlying methods)

I hope this somehow helps…

Happy coding :slight_smile: