x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

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?

Product Version: Not Selected
Tags:
more ▼

asked Dec 11 '18 at 05:27 AM in C++ Programming

avatar image

kozmyukv
1 2

(comments are locked)
10|2000 characters needed characters left

3 answers: sort voted first

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.

more ▼

answered Dec 13 '18 at 10:07 AM

avatar image

kozmyukv
1 2

(comments are locked)
10|2000 characters needed characters left

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.

more ▼

answered Dec 11 '18 at 10:55 AM

avatar image

Bariudol
556 19 12 27

(comments are locked)
10|2000 characters needed characters left

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.

more ▼

answered Dec 11 '18 at 10:48 AM

avatar image

staticvoidlol
2.6k 94 40 111

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question