[Question] Damage types and Components

I was wondering what the reason is behind having hardcoded DamageType classes if the base Weapon functionality was entirely removed. Are there any optimizations there, if so what are they for?

The reason I ask is it makes sense (to me atleast) to have damage applied as a component because its not always a singular event, it can be a continuous event much like walking or running (vs jumping). With a component based system I can also provide either a HUD component or directly, display information for Overriding post processing etc.

I actually made my own system that works similar in principle (it modifies actor to which effect/damage is applied), although I didn’t used component.

Components can be tricky to remove. Especially when you try to remove component from one actor using another actor (or object).

Although good question. I’m also curious what is the purpose of DamageType class;

Hi Daniel,

While a damage component makes sense in some situations (poison, etc.), it isn’t necessarily the best choice in all situations (like an area of effect, where you’d probably prefer to be taking damage directly from a container volume). It seems like a game specific decision, and therefore won’t likely be introduced to the engine.

That said, there’s nothing keeping you from implementing this system yourself. You can easily subclass UActorComponent to create your own UDoTComponent, which could accumulate damage and apply it periodically via UActor::TakeDamage().

As for DamageType, it serves as a base class that games can subclass and add information to. While there’s no weapon information in there now, there’s nothing stopping you from inheriting from it and adding your own (if your project needs that kind of info). If you do that, then it’s nice to still handle that damage in a single choke point (i.e. the TakeDamage() function), and elsewhere (when you need the weapon info) you can cast it to your inherited type. You wouldn’t want to handle both damage types separately, if they both do the same thing (like subtract health).

Well the main reason I asked is that DamageType is a required part of the DamageEvent struct and Im not really given the choice whether I want to use it or not. I was wondering if there was any hard limit that would disagree with me breaking the functionality and simply always passing the same DamageType class because I honestly dont require a Class per, it ends up making the system quite tedious when a simple enum suffices.

Honestly Id prefer if I could pass the variables directly into the TakeDamage function instead of a structure containing a class I dont have any use for. Unless there is some reason they have to be static classes, like replication or security.

There is nothing stopping you from using just plain FDamageEvent, and setting it up so it always sets DamageTypeClass to UDamageType.

In fact, if you use the default constructor it looks like everywhere it handles an empty DamageTypeClass as UDamageType.

This being said, you won’t receive any “point” or “radial” damage. Those have to come from FPointDamageEvent or FRadialDamageEvent respectively.

The reason why there are different structs for each of these (and not just a enum identifying the separation) is that GetBestHitInfo() is different per type. The hit info is computed differently for each of those.

It’s probably bit of topic, but why TakeDamage in actor doesn’t take DamageType as argument ? The blueprint node for dealing damage (Apply Damage), which calls TakeDamage take DamageType argument, but since actor function doesn’t it seems like the DamageType for Apply Damage do nothing. Or at least nothing meaningful, that we can take advantage of.

DamageTypeClass is part of the FDamageEvent struct that gets passed to TakeDamage. So ApplyDamage takes the DamageType argument, constructs an appropriate FDamageEvent, then calls TakeDamage with that.

Oh I understand that for the built in types but my concern is with the layer ontop of that being limited. That while I can always use a UDamageType of the same class I still need to access the variables within it so essentially I need to create the class variables regardless if I use the class or not.

Basically Im wanting to use FPoint and FRadial damage more directly if possible, then I can make the differentiation in my own structs/enum types and not have to duplicate the data or be limited to creating subclasses per.

There are instances where I have damage types that are both radial and point depending on the circumstances and there are also dual damage types that are both at the same time.

The FDamageEvent is designed to be extended by games, so you can easily create FMySpecialDamageEvent and add whatever data you need. You can also create custom DamageTypes and add whatever handlers or BP hooks you need (e.g. UMySpecialDamageType::OnPawnDamage() ). You’d probably need to create some custom BP actions to go along with these, but that shouldn’t be too hard either.

Yup thanks, I looked into this in more detail and I did answer part of my own question in doing that. Hopefully I’ll be able to get the results Im looking for, if I cant I’ll post up another thread with some specifics. Thanks for taking the time to answer my questions.