Post by Damian on May 13, 2015 13:21:33 GMT 10
It's been a while since the last development log. That's because I have been knee deep in research and code for the melee system.
The magic projectile system was easy. Simply test the target is in range by comparing root positions, spawn a projectile, apply a linear force to the projectile and then detect when it collides with something. Easy.
The melee system proved to be more difficult problem than I had anticipated.
The assumptions were
Initially I thought I'd be clever and model a physically correct system for detecting collisions. By that I mean 2 colliders meet in 3D space and a collision is detected and somebody bleeds.
The idea was simple
This approach kind of worked, but was far from reliable.
Firstly, the additional colliders in the scene consumed a lot of resources and having many characters on screen busily swinging at each other really reduced the frame rate.
Secondly, the physical nature of the collisions required the attacker to bend at the waist to face the target and the swing animations had to IK overridden to pass through the space at the required elevation and attack vector.
Thirdly, the weapon trigger collider needed code to only apply damage once per target as the sword could be inside an enemy body collider for multiple frames
The result was a lot of code required to override IK and a huge performance hit for managing colliders that yielded a jittery, low accuracy, frustrating experience.
I'm sure I could have made this system work with a great deal of time and effort, but it seemed that I could achieve the desired result with a lot less work.
It did not take long to find that most indie studios and AAA studios detect melee collisions by "faking" the physical method I first attempted.
I came up with the new approach which has worked out beautifully.
This is just a first pass, but it's 100% simpler, more efficient and much more satisfying.
If anybody has a suggestion on how I could improve on this method or an entirely different approach I'd be interested in hearing from you.
The magic projectile system was easy. Simply test the target is in range by comparing root positions, spawn a projectile, apply a linear force to the projectile and then detect when it collides with something. Easy.
The melee system proved to be more difficult problem than I had anticipated.
The assumptions were
- The blade has to be "live" for a small portion of the swing animation.
- Damage should be able to apply to multiple enemies as the "live" blade passes through 3D space
Initially I thought I'd be clever and model a physically correct system for detecting collisions. By that I mean 2 colliders meet in 3D space and a collision is detected and somebody bleeds.
The idea was simple
- Add a physical collider to each body part i.e. head, arms, torso, legs.
- Add a kinematic rigidbody and trigger collider to the sword, halberd, axe, etc.
- Use Animation Events to set the blade as Live and Not Live.
- Detect OnColission event for weapon trigger collider
- Apply damage
This approach kind of worked, but was far from reliable.
Firstly, the additional colliders in the scene consumed a lot of resources and having many characters on screen busily swinging at each other really reduced the frame rate.
Secondly, the physical nature of the collisions required the attacker to bend at the waist to face the target and the swing animations had to IK overridden to pass through the space at the required elevation and attack vector.
Thirdly, the weapon trigger collider needed code to only apply damage once per target as the sword could be inside an enemy body collider for multiple frames
The result was a lot of code required to override IK and a huge performance hit for managing colliders that yielded a jittery, low accuracy, frustrating experience.
I'm sure I could have made this system work with a great deal of time and effort, but it seemed that I could achieve the desired result with a lot less work.
It did not take long to find that most indie studios and AAA studios detect melee collisions by "faking" the physical method I first attempted.
I came up with the new approach which has worked out beautifully.
- Detect the midpoint of the swing animation with an Animation Event
- Check if there are any targets within the "angle of attack" for the swing with a Dot product e.g. 20 degrees in front of attacker
- Check if enemies are within range of the weapon with LineCast
- Apply damage
This is just a first pass, but it's 100% simpler, more efficient and much more satisfying.
If anybody has a suggestion on how I could improve on this method or an entirely different approach I'd be interested in hearing from you.