ActorComponent - ensuring that parent has certain function

So in the game I have a bunch of different actors - players, enemies, buildings, etc. Those actors share a quality - they have HP, can be attacked and destroyed.

For that purpose I’ve created an ActorComponent that I’ve called HealthComponent, that handles tracking down health, taking damage, regenerating health, etc.

Now, in that component, when Health reaches 0, I would like to call Death() function, but I want the implementation of that function to be different based on what this component is attached to. So Ideally I want to call a function on the parent, and let each parent handle it accordingly.

However, in C++ I obviously can’t compile the code that calls a function that doesn’t exist.

How can I ensure that the function exists, when I attach the component to the parent? Is there some other way to work around that? Is there something I’m missing?

Ideally you would want to have all your actors that share certain “core” functionallity inheriting from the same class. In your case you could have for instance a YourGameCharacterBase class with the methods you need like:

on the h file:

virtual void Death();

on the cpp file:

void YourGameCharacterBase::Death() { //DO NOTHING IN THE BASE CLASS }

then in your child classes you simply override that method:

virtual void Death() override;

Moreover, you dont even need that component if you work with inheritance in that way, which is one of the great advantages of object oriented programming.

However, if you cant restructure your classes to meet this inheritance paradigm, using an interface like staticvoidlol sugests is a more than valid solution too.

The only way I can think of doing this in your current situation would be to create an interface with a function called e.g. “Death”. Then you’ll need to implement this interface on your relevant actors and you can have different behaviours specified in the classes when “Death” is called. Then when the HealthComponent’s Health reaches zero it can get its parent, check if the parent implements the interface by casting and if so call the Death function.

So in the end I did it through delegates. I basically made a delegate on my component:

DECLARE_DELEGATE(FDeathEventDelegate);

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT_API UHealthComponent : public UActorComponent
{
{
	GENERATED_BODY()

public:	

	// Event handler for Death event
	FDeathEventDelegate OnDeath;
...
}

and then in the damage handling code, I invoke that delegate’s code, if it exists:

    // check if object is dead
	if (m_health <= 0)
	{
		// Die
		OnDeath.ExecuteIfBound();
	}

Then, the owner Actor can have a function and subscribe it to that delegate. Or it can ignore it, and Health component will continue to work - it just won’t have anything happening when HP reaches 0. I made similar event for taking damage - for example if the Owner wants to display something on screen each time it takes damage or react in some other manner. That way the reduction of HP is handled by health component, and any other specific reactions are handled on the owner.

class MyActor: public AActor
{
  // ctor
  MyActor()
  {
    FindComponentByClass<UHealthComponent>()->OnDeath.AddDynamic(this, &DeathHandler);
  }

  //Death Handler
  void DeathHandler()
  {
    //react to death event
  }

}

Obviously it’s oversimplified. Ideally you first check if HealthComponent exists before binding the function to a delegate, but I guess those specifics are easy to figure out for anyone who wanted an answer.