A trace-based approach to melee hit detection: suggestions?

For a while now I’ve been using capsule component overlaps to register melee contact in my game. However, this system is very limited because Unreal does not report location or normal data for overlaps.

So what I’ve considered doing is swept-shape tests instead of overlaps. These provide the advantage of giving me actual contact-location data for each individual swing. However, I’m running into some problens and I’m wondering if anyone has any insight.

My first attempt involved the same sort of shape traces many people do; simply tracing down the length of the weapon from base to tip in order to determine contact. There are two main problems, though:
(1) attacks always register contact from the front, rather than the side; if you swipe a sword from right to left, you’re making contact via the leading edge moving in a leftward direction on the side of the enemy; however, the trace will report a frontal contact since it’s firing down the length of the blade.
(2) with fast attacks, it’s possible for hits to miss entirely if the sword is, for instance, to the right of the enemy one frame, and to the left of the enemy the next. The traces can only fire every tick (unlike collision detection which can be continuous even if a frame doesn’t show collision).

So my next attempt involved using box traces, using some math and some socket locations to orient the boxes themselves, which traced from the last position of the sockets to the current position every tick. This works better, but ALSO has some problems:

(1) box traces do not rotate between start and end. What this means is that if the sword rotates 5° every tick, the box trace will appear like a fan with triangles cut in it where the orientation of the box changed between the end of the last trace and the start of the next one. This isn’t typically a big deal but for attacks with a long weapon it’s possible for an enemy to fall inside these triangles.
(2) A collision component knows when it starts and stops colliding. An attack which passes through an enemy across 3 frames knows that it should only start damaging on the FIRST contact. Tracing, however, does not; a Do-Once node doesn’t work here, either, since you need to tell the enemy to reset that node when the trace STOPS making hits, and once the trace stops making hits you lose your reference to that enemy (you could store it as a variable but this poses problems for attacks which contact multiple enemies; an array could theoretically work but then the performance cost of looping through it every tick seems like it wouldn’t be worth it relative to regular overlap checking).

So I’m kind of curious if anyone has any thoughts on a good way to go about getting contact data using traces in a way that retains the accuray of UE4’s overlap detection systems.

This is an excellent question, I have played with both and what I have decided to do is just fire damage and fire impulse in front of the character and don’t use any Trace components or hid boxes or lunch and d anytime you punch then the damage and impulse buyers a few feet in front of the player

Couple of thoughts:

Rama’s Melee Weapon Plugin does what you are describing. It sweeps the collision shapes setup on the weapon physics asset. And you get the c++ source. I would start here. Rama's Melee Weapon Plugin in Code Plugins - UE Marketplace

If you want to dig further after that…then remember:

At low framerates, for fast animations, the swept trace may not be accurate. You could evaluate the animation multiple times per frame - but that will cause the framerate to reduce further. eg…just query the bone position from the raw animation sequence data.

For each attack animation, you could also store pre-swept curve data somewhere and simply use that to sweep at a higher frequency for increased accuracy. This would require creating some kind of pre-processing.

In regards to (2) - simply trace each frame, record all hits, filter to unique enemies to avoid damaging twice. I do not understand the issue you are having?