Damage in AAK is a multi stage process that lets a sender, receiver and kind of damage interact. In PreDamage the sender and receiver are informed that a damage is about to occur between them, they both have the chance to completely cancel the damage here. During OnDamage each kind of damage that the sender has is packaged into a damage event that gets send to all the participants. This is where a senders and receivers can modify the damage value and where the DamageKind applies whatever effect the damage has. Finally in PostDamage the sender and receiver have a chance to react to the combined changes of the applied damages.
An IDamageSender is any component that causes damage occurences. It can be implemented by any class that sends damage. You can Use the static DamageEvent.Send to send your damages. AAK comes with a TriggerDamageSender that uses that regular Unity trigger messages(OnTriggerEnter, …). By default it only sends damage when a TriggerDamageRecevier first enters but it can also be configured to send damage in intervals or at the end.
AAK also comes with the DestructibleDamageReceiver which destroys(or replaces) its gameobject when it gets damaged. This is ideal for destructible environment object or any other object that needs to get damages but does not warrant a full character.
Both the TriggerDamageSender and the TriggerDamageReceiver forward all their damage calls to the character they are attached to(if any). Therefore if we want to react to any kind of damage done to a character we can conveniently do that in the character implementation. The SuspendSendDamage and SuspendReceiveDamage character instructions hook in here.
Damages can theoreticalls be anything, what exactly a damage does is decided by the DamageKind implementation. The most common kind of damage is removing a resource(HP) from a characters ResourcePool. AAK comes with the ResourceDamage damage kind which does exactly this.(ContextMenu>Aventure/ResourceDamage)
Somewhat more complicated than a lot of other games damage in the souls demo is split into physical and poise damage. Poise damage is generally used to signify the brunt of an attack rather then the pure health malus.
The base character defines a lot of the damage handling in the demo. Parries are checked in PreDamageReceive so that the damage can be cancelled if a parry succeeds. In OnDamageReceive the damage value is reduced by defense or set to 0 when a character is guarding. In PostDamageReceive it checks if the charcter dies or is staggered as a result of the damages applied.
One thing we need to make sure is that a player does not damage itself. We could theoretically just cancel any damage that a player weapon might do to the player in PreDamage but using Layers is far more convenient and performant.
The AdventureSouls demo has various Layers that control which objects can interact with each other. Check the Pyhsics settings to see how exactly they are configured.
The player has a general Player Layer that is used for any kind of logical interaction like entering areas or object interactions. The PlayerBody Layer is used to receive damage and interact with physics objects like derstroyed crates. In the current demo the body, just like the logic, uses a simple capsule collider. To get more exact hitboxes and more interesting phyiscs interactions the PlayerBody is the one that should be changed to have more detail. Lastly PlayerDamage is used on any weapons the player uses and interascts mostly with EnemyBody.
The Enemy has a very similar setup to the player with the Enemy, EnemyBody and EnemyDamage Layers. There is also a NeutralDamage Layer that is used by traps so they can send damage to either character. The Trigger Layer is used for logical area to make sure these do not interact with damages or physics at all.