Announcement

Collapse
No announcement yet.

Damage!

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    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.

    Code:
    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!
    Senior Engine Programmer, UE4, Epic Games
    Twitter:
    @Byooler

    #2
    awesome, gonna look into this.

    Comment


      #3
      Nice write up, thanks!

      Comment


        #4
        Thank you, can you do one on delegates next please?
        Cheers!

        Comment


          #5
          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
          Core i7-8700K @ 4.8 GHz
          2x ASUS GTX 970 STRIX SLI @ 1450/7600
          Z370 AORUS Gaming 7
          32 GB G.Skill Trident DDR4-3200
          EVGA 850 G2
          850 Evo 500 + 840 Evo 256

          Comment


            #6
            So, can I "accumulate" damage now, like I made here?: https://vimeo.com/23603834



            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: https://vimeo.com/23614124



            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 here: https://vimeo.com/23614824



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

            Comment


              #7
              Originally posted by Lordink View Post
              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.
              Senior Engine Programmer, UE4, Epic Games
              Twitter:
              @Byooler

              Comment


                #8
                Originally posted by RoadStar View Post
                I have a question: can I start an animation of by bring a damage to they "parent"? Like here: https://vimeo.com/23614824
                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.
                Senior Engine Programmer, UE4, Epic Games
                Twitter:
                @Byooler

                Comment


                  #9
                  Originally posted by Jeff Farris View Post
                  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 Is there any workaround u guys r using at Epic?
                  Core i7-8700K @ 4.8 GHz
                  2x ASUS GTX 970 STRIX SLI @ 1450/7600
                  Z370 AORUS Gaming 7
                  32 GB G.Skill Trident DDR4-3200
                  EVGA 850 G2
                  850 Evo 500 + 840 Evo 256

                  Comment


                    #10
                    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?

                    Comment


                      #11
                      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.
                      Adam Davis | Marketplace Support | Epic Games
                      How to report a bug? | Installation & Setup issues? | Answerhub Bug Reports | Twitter

                      Comment


                        #12
                        Adam,
                        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!

                        Comment


                          #13
                          You can use the bones that have bodies in the physics asset. FHitResult will contain a BoneName for hits on skeletal meshes.
                          Senior Engine Programmer, UE4, Epic Games
                          Twitter:
                          @Byooler

                          Comment


                            #14
                            Dear Jeff,

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

                            Thanks for sharing!

                            Rama
                            100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                            UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                            Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                            Comment


                              #15
                              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.
                              Storyteller - An immersive VR audiobook player

                              Dungeon Survival - WIP First person dungeon crawler with a focus on survival and environmental gameplay ala roguelikes

                              Comment

                              Working...
                              X