Damage!

[]
“If an injury has to be done to a man it should be so severe that his vengeance need not be feared.”

  • Niccolo Machiavelli
    [/]

“Damage” is a common concept in games, so I wanted to give a quick primer on the damage functionality we’ve included in the UE4 game framework.

Damage support is a feature of the base Actor class, making it widely available. The system provides easy access to common functionality for quick results, while also being extensible to allow you to customize your damage model when needed. We’ve also made an effort to avoid making assumptions about how to respond to damage, meaning you won’t find any notion of “hit points” or “death” in the engine. These concepts tend to be very game-specific, and we’ve found that attempts to generalize them end up causing more pain than they prevent.

Basic damage-related concepts
There are a few commonly-used concepts we use when talking about damage that I’ll cover quickly.

DamageType
As the name suggests, a DamageType is an object used to describe the “type” of damage, independent of its origin. This can be a very useful concept if you have many sources of damage and you want common functionality between them.
An easy example to illustrate this would be fire damage. Let’s say you want anyone who takes fire damage to yell “WOW SO HOT” and run to the nearest water. Rather than duplicate code to do this into every actor that can burn the player (or for every type of actor who could be burned), you can define a damage type for fire (UDamageTypeFire), give it some type of HandleDamagedCharacter() function, and call it appropriately from your TakeDamage() call chain.

Instigator
The Instigator is who caused the damage, typically a PlayerController or an AIController. In the case of fire damage, this might be the player or AI who lit the fire.

DamageCauser
The “causer” is usually what caused the damage, such as the ACampFire actor that you just walked through.

Damage in C++
Let’s look first at damage support in native code. In this case, damaging an actor is simple – just call TakeDamage() on it.


virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser);

Likewise, to respond to damage, simply override TakeDamage() on the receiving actor and insert your custom handling. Easy!

You’ll notice that the TakeDamage() call accepts a DamageEvent as a parameter. This FDamageEvent data structure contains data about the specific circumstances of the damaging event so that your response code can react appropriately. UE4 comes with 3 flavors of damage event built-in.

FPointDamageEvent
“This particular spot on my face hurts because it got hit from that direction.”
A point damage event models damage applied at a specific point on the victim, such as from a bullet or a punch. It contains the direction the hit came from and a FHitResult that describes the surface impact.

**FRadialDamageEvent **
“My whole left side hurts because of that big blast over there.”
A radial damage event models radial damage from a point source, the obvious example being from an explosion. It contains the epicenter of the blast, data to describe the damage falloff through space, and a list of affected components.

**FDamageEvent **
“Ow.”
This is the most generic damage model available, containing only an optional DamageTypeClass.
If none of these built-in events types meets your needs, you can derive your own structure from FDamageEvent and store whatever data you need.

Damage in Blueprints
Dealing with damage in Blueprints is similar, except the damage application and responses are already broken out by event type. There are globally-accessible nodes available to inflict damage, such as ApplyDamage, ApplyPointDamage, and ApplyRadialDamage. To respond to damage events, there is a similar suite of “took damage” events for both actor classes and for actor instances within the level.

If you define custom damage events for your project, you will probably want to expose a similar set of functions and delegates for use in Blueprints.

Happy damaging! And for damage-related inquiries and anecdotes, post below!

1 Like

awesome, gonna look into this.

Nice write up, thanks! :slight_smile:

Thank you, can you do one on delegates next please? :slight_smile:
Cheers!

Thanks, that’s the information I was actually looking for. Also, I would be happy if you could give a little advice:
If I want to implement a pretty generic damage system, where player can receive damage from physical interactions (like in Source) and of course bullets etc, and those all will be decreasing his health and showing some post-process while damaged, what is the best code design solution for this? Should I override TakeDamage() for my character class to include post process and health decrease?
And, as far as I see, physical interactions do not invoke TakeDamage() for now, so I also would have to override OnHit() event and check in it, how powerful was the hit so that I could invoke TakeDamage() if needed?
Thanks in advance :slight_smile:

So, can I “accumulate” damage now, like I made ?: Destructible dynamic covers on Vimeo


As you can see, I can “kill” wooden planks from the box by shooting them, but finally box will be destroyed after some “critical volume of damage” accumulated with destroying of each plank.

Another RnD video: Destructible Glass dynamic setup test on Vimeo


I can bring the damage from frame to glass, from one piece of glass to “neighbors” and even from glass to frame.

I have a question: can I start an animation of by bring a damage to they “parent”? Like : Heavy vault attached to helicopter on Vimeo


This could work VERY well for chunks, pieces, debrises etc…

[=Lordink;55604]

If I want to implement a pretty generic damage system, where player can receive damage from physical interactions (like in Source) and of course bullets etc, and those all will be decreasing his health and showing some post-process while damaged, what is the best code design solution for this? Should I override TakeDamage() for my character class to include post process and health decrease?
And, as far as I see, physical interactions do not invoke TakeDamage() for now, so I also would have to override OnHit() event and check in it, how powerful was the hit so that I could invoke TakeDamage() if needed?

[/]

Yeah, I think you’ve got the right idea there. For interactions you want to cause damage, call TakeDamage(). To do damage response effects (e.g. PP adjustments), override TakeDamage and handle it in there.

One caveat would be if you can modify your health from multiple code paths, such as a Gears-style delayed autoheal, you’ll want to be able to update your PP when that happens as well. Or just drive it off of Health and update it every tick.

[=RoadStar;55651]
I have a question: can I start an animation of by bring a damage to they “parent”? Like : Heavy vault attached to helicopter on Vimeo
[/]

Sure! You should be free to run arbitrary code in response to your TakeDamage call. Play animations, control other objects, spawn something, calculate PI to 10000 digits, whatever you can think of. :slight_smile:

[=Jeff Farris;55834]
Yeah, I think you’ve got the right idea there. For interactions you want to cause damage, call TakeDamage(). To do damage response effects (e.g. PP adjustments), override TakeDamage and handle it in there.

One caveat would be if you can modify your health from multiple code paths, such as a Gears-style delayed autoheal, you’ll want to be able to update your PP when that happens as well. Or just drive it off of Health and update it every tick.
[/]

Thanks, I got it. However, while I was trying to implement damage on character physical hit, I did not find any safe way to get the hit power. There is no such parameter in hit data and ReceiveHit() event arguments. I then tried to get the hit power myself, using the mass of hit body and its’ velocity at hit moment, which I got from hit event. That made the game crash, as OnHit() gets invoked while Pawn hits the ground, which is BSP geometry. Getting mass or velocity from BSP geometry throws an error, for quite obvious reasons :frowning: Is there any workaround u guys r using at Epic? :slight_smile:

Where would I start looking if I wanted to do location based damage? Is there an example that has damage checking for location? i.e. hits to head/torso/arm/leg and being able to check and how hits register to different locations? If not where should I start looking to do this?

Hi Nemesis,

You may try adding sphere or capsule components over the body and then, when the hit lands, have it relay the location, if the trace returns hit: Head, do x damage, if it returns hit: Leg, do Y damage.

Another way to do this, albeit a highly math heavy solution, may be to calculate where the damage occurred based on vector location. You could run a hit trace to determine a hit, then, based on hit location, check to see how far away from the root component and in what direction the hit occurred. For instance, let us say the head is ~100 uu above the root at the waist, then you can say if >= 0,0,100 do X damage. Similarly, if the arms are resting along your Y axis, you can say if >= 0,50,0 do Y damage. There is probably going to be a lot more to this than I am making it out to be, and as I haven’t tried it myself I honestly couldn’t tell you how much work this might involve, but it is a potential solution to location based damage. Overall, I would recommend the first option and just search for specifically named hit-boxes.

,
Using the spheres/capsules sounds like a good start. Is there a way to use the bones that are in a model? Or are those not addressable in engine (by default)?
Thanks for the pointer tho!

You can use the bones that have bodies in the physics asset. FHitResult will contain a BoneName for hits on skeletal meshes.

Dear Jeff,

I really like your writing style in the original post, fun and clear and informative!

Thanks for sharing!

Is there any equivalent of UDK’s HitMask in UE4? I’m in need of some way to apply textures onto my character at a given point.