2
\$\begingroup\$

I have been working on a RTS game in unity and did damage deal through code and a timer but it does not fit with the animations quet well. The damage is dealt in the beginning of the animation and about 4 attacks it fits perfectly and after more 4 attacks the damage is dealt delayed after the animation.

My big question is if hitboxes would be a good answer to solve this problem or is it to preformance heavy?

\$\endgroup\$
  • \$\begingroup\$ You should look for a way to better synchronize animations and game mechanics. \$\endgroup\$ – Philipp Feb 25 '15 at 8:21
  • \$\begingroup\$ you dont need hitboxes, they will be expensive for numerous of units. In mechanim, you can call methods on any frame of an animation. You dont show us how you do what you do, but if you simply create a dmg dealing method and call it on the correct frame of the animation, all should be well. \$\endgroup\$ – K.L. Feb 25 '15 at 8:28
2
\$\begingroup\$

I think the approach you are probably looking for is to trigger damage based on some event, which is keyed to a particular time or frame in the animation. I'm not sure exactly how you can set this up in your case as I'm not familiar with the specific tools etc. but the general concept would be:

  1. For each attack animation, define at which frame / time offset the damage is applied.
  2. Watch for this event happening in code, or check each frame after starting the animation to test if the specified time has past.
  3. When the event is triggered or the time past you can then apply the damage. At this point you should know everything you need to such as: The unit attacking (hence it's damage and stats), the unit being attacked (hence the appropriate target and it's defenses etc) so you can apply the damage appropriately.

Some advantages of an approach like this are:

  • You can pick the damage event time to coincide with the the sword swing, or the muzzle flash etc. This signifies the "active" or "hit" portion of the animation so you can tweak it to make it look right. Potentially you can also manage DoT attacks, or attacks which persist for multiple frames in a similar way by recording a time period that the attack is active, though you then need more complex code to handle how multiple hits to the same unit are processed.

  • It's a fairly light system and should not need much overhead (in code or cycles). If your units are already capable of attacking each other then you already have all the targeting information, and presumably the damage calculation setup. All you need to incorporate is the timing aspect, which should be driven from the animation.

  • It's data driven (either via the animation, or easy to make so via your game files), so should be easy to tweak / change over time as you iterate on your units. This also helps for modding etc.

Having written a hitbox system myself from scratch, I'd say that it's almost certainly overkill for a game like you have described, certainly as a first iteration. There is a lot more overhead in terms of code (and performance) to manage life-cycle of hit/hurtboxes and checking for their intersections.

They do give good results, and can be fairly straightforwards if you limit the hitbox shapes permitted to rectangles, but I'd start simple and work up as you need it.

\$\endgroup\$
  • \$\begingroup\$ To emphasize here: It's important you detect whether the event has passed, not just whether it is happening right this frame, because you might be dropping frames under load. \$\endgroup\$ – uliwitness Feb 27 '15 at 17:32
  • \$\begingroup\$ This sounds good, just have to figure out how to do that with Animator \$\endgroup\$ – Le_cow Feb 28 '15 at 14:42
  • \$\begingroup\$ @uliwitness: Yes, this is crucial and I see your point now. When I was discussing an event driven by the animation, as supposed to tracking the timing manually, I was imagining that if such a feature were provided by the animation engine / sub-system that it would handle this automatically. Should have spelled this out, good point. \$\endgroup\$ – xan Mar 2 '15 at 9:26
0
\$\begingroup\$

I can see several issues:

  1. You should probably deal the damage at the end of the animation. That way, if the damage causes the opponent to die, the animation is done and doesn't keep waving the sword over a dead body. If you can, break your animation up into several steps and deal the damage in several smaller increments, and just stop dishing out damage once the opponent has died.

  2. The secret behind animation timing is to self-correct while animations are playing and equate animations with actual time stamps. I'd expect Unity to do that for you already. What one usually does is decide on a frame rate (e.g. 24fps) and a start time, and then to periodically (e.g. from a timer or a display link callback, vertical blanking interrupt or whatever your platform offers) call your drawing code. The drawing code now doesn't draw the next frame, but rather, based on the difference between the start time and the current time, draws the frame that is scheduled to be drawn right now:

    currentFrame = (currentTimeSeconds -animationStartTimeSeconds) / framesPerSecond
    

    This means that on a slow machine, gameplay will still have the same speed, though you may get dropped frames.

    The advantage of this is that you can now use the same mechanism to schedule when how much damage is dealt and when the animation should end. If your timers drift, you just run them a little more often, and they will draw the right frame even if they skip one frame.

\$\endgroup\$
  • \$\begingroup\$ I don't agree with 1, at least in general. If your attack animation is a sword swing then it may look very odd if damage is not applied till the swing has finished. If the damage comes mid-blow and the attack kills, is there harm in continuing the swing to completion? Again, I'd say that would look more correct in general. I don't think your point 2) is addressing the main point of the question, which is how to get the point at which the damage is applied to match the animation. \$\endgroup\$ – xan Feb 27 '15 at 15:48
  • \$\begingroup\$ It's the same mechanism no matter when you want them to sync up: Make sure your animation is able to drop frames, so if a frame is drawn at all (it might not be drawn if your computer is under load, and that's fine), it is always drawn at the same relative time. Then you can just make note of at what time your animation actually should cause the damage and trigger your action then, knowing animation and damage will sync up. It's the same technique used by video players for A/V sync. \$\endgroup\$ – uliwitness Feb 27 '15 at 17:25
  • \$\begingroup\$ Alternately, if your game is not a multiplayer online game (where you wouldn't want to trust the player's computer with detecting stuff like that), you can ensure that the important frame gets drawn at the least (just by keeping track in an ivar whether it has been drawn) and then do actual collision detection of the models to detect a hit or miss. But for most cases, just detecting distance is good enough and doesn't require keeping track of whether a frame was dropped. \$\endgroup\$ – uliwitness Feb 27 '15 at 17:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.