Frame-specific attacks in Unity

Sept. 3, 2019
protect

Frame-specific attacks in Unity

Explanation

Why would I want to check specific frames? There's several situations where checking if an animation is in a specific frame comes in handy:

 

  • If you remember my previous post about Hitboxes and Hurtboxes, one of the qualities we needed our hitboxes to have was that It should be able to check if it’s overlapping a Hurtbox in arbitrary frames. 

  • Suppose you are making an action game and you want to have combos. You'll probably need a way to tell if an attack animation is in a frame that can be interrupted to chain the next move. Yo wouldn't want to chain the next punch if the first one didn't reached a certain point in the animation.

  • Maybe you want to have a certain range of frames marked as parryable, probably a few frames before the attack connects.

  • You could have a window of oportunity after a character misses an attack where getting hit makes more damage.

Examples are endless, but you can see where this is going: More control over our animations gives us more possibilities.

 

The underlying logic (and code) for all the situations I mentioned will be the same, but in this post I'll center in one of those cases: I want to be able to tell  an attack how many frames of startup, hit and recovery it has. Or in other words, Move Stages.

 

Animation, Frames and Move Stages

So what do we see when we watch a fighting or action game? Characters fighting each other, is it not obvious? You may say, and you would be correct. But if we look deeper, what we are actually seeing are animation frames. Sprites being rendered one after the other at a fixed rate (Or polygons being moved and deformed at a fixed rate if you are in a 3D enviroment). 

This "fixed rate" is usually 60 or 30 frames per second for 3D games. In 2D games it depends on what the developer or artist wants: More frames per second will give you a smoother and more detailed animation, but it means more sprites need to be created for every action. Note that we are talking about animation frames and not the speed the game runs at. For a fighting game to be responsive enough to be good it should at least detect the player input at a high framerate, indepentendly of the type of animation used.

 

SF3 runs at 60fps but it's animated at a much lower framerate (And it looks awesome).

 

As your probably know, an animation is composed of frames and has a duration that we can also measure in frames. Why would we want to measure an animation in frames? because as we stated previously we want to check if our animation is playing a specific frame. 

When you trigger an attack in a game it doesn't automatically hit the enemy. The character starts the animation by preparing the attack, it hits for some amount of time and then recovers from the movement. Playing with the duration of those phases is how you get "heavier" or "lighter" characters, moves or weapons.

Here's an example from Dark Souls, a quick Rapier that does small amounts of damage vs. a slower Great Club that does enourmos damage.

 

Pay attention to the really long startup of the club

 

Those stages of an attack animation are called Move Stages. Or Attack Phases, or any combination of those 4 words. As always, it depends on who you ask. I'll call them Move Stages just to be consistent.

 

Move Stages

As we mentioned, an attack has 3 stages:

  • Startup: The frames before the attack hits, where the character is setting up the move.

  • Active frames: The frames where the attack is hitting and hitboxes are checking collisions.

  • Recovery: The frames after the attack hits or misses, where the character recovers.

Here's a nice graphic from Shoryuken.com:

 

 

 

So when do we want our Hitboxes to check for collisions? You guessed right, in the Active Frames Stage.

Now that we know what we want, let's get to work! (This may seem obvious but never underestimate the power of actually knowing what problem you are trying to solve)

 

Quick solutions

As with every problem, there's the quick way and there's the more complicated way. Note that I didn't say one is right and one is wrongWhich solution you choose should respond to what problem you have, the scope of the problem and how much time you are willing to invest to solve it. Don't let yourself be distracted of your objective because some coding guru told you that the right way to iterate an array is an incredibly performant-functional-disruptive way that would take you 2 months to implement when you had it solved and working perfectly in 5 minutes with a for loop.

 

Okay, rant over.

There's 2 standard ways to change script values in specific frames of an animation:

  • Animating the parameters: You can simply turn hitboxes on and off or change public script values while animating your character.

  • Animation Events: You can add Animation Events to any frame you like of an animation and trigger a method from a class that is in the same GameObject. Check here if you don't know what I'm talking about.

These two methods could work perfectly depending on the needs of your game, and you can implement any of them in 5 minutes, so really evaluate what you need.

 

The problems

  • No reusability: You will have to go animation by animation modifying the values in the frames you want. 

  • Mixing animation and events: If you are doing everything by yourself this may not be a problem, but if you work with an artist having animation events or setting values in them could lead to mistakes when changing animations.

  • If using animation events you will need to have all the code in a monolitic class that the animations can access.

 

JikGuard.com, a high-tech security service provider focusing on game protection and anti-cheat, is committed to helping game companies solve the problem of cheats and hacks, and providing deeply integrated encryption protection solutions for games.

Read More>>