- Home /
How can I do frame by frame hitbox control for a 2D fighting game character?
I have created a 3D model and some basic walk, run, idle, and attack animations in blender. I would like to import these into a 2D unity fighting game and be able to control the hitboxes of the attacks on a frame by frame basis. Is this possible? Is there a tutorial or something showing how this is done in unity?
been looking for a way to achieve the same result for a while with no luck yet.
Just copy and pasted into Untiy 5 (Im sorry Ill edit it once I get better at scripting) and the colliders are there but the hitboxes don't clear. one is always hanging around. Any suggestions?
Answer by Lovelock · Oct 12, 2014 at 06:12 AM
This isn't the prettiest solution but it gets the job done. I'm using 2D Sprites but it can be applied to 3D GameObjects as well.
This system has three parts:
A HitboxManager script to swap hitboxes when needed
Animation Events that tell the HitboxManager when to draw hitboxes
A reference hitbox for each frame that needs a hitbox
Before we get started, here's an example of a HitboxManager script:
using UnityEngine;
using System.Collections;
public class HeroHitBoxManager : MonoBehaviour {
// Set these in the editor
public PolygonCollider2D frame2;
public PolygonCollider2D frame3;
// Used for organization
private PolygonCollider2D[] colliders;
// Collider on this game object
private PolygonCollider2D localCollider;
// We say box, but we're still using polygons.
public enum hitBoxes
{
frame2Box,
frame3Box,
clear // special case to remove all boxes
}
void Start()
{
// Set up an array so our script can more easily set up the hit boxes
colliders = new PolygonCollider2D[]{frame2, frame3};
// Create a polygon collider
localCollider = gameObject.AddComponent<PolygonCollider2D>();
localCollider.isTrigger = true; // Set as a trigger so it doesn't collide with our environment
localCollider.pathCount = 0; // Clear auto-generated polygons
}
void OnTriggerEnter2D(Collider2D col)
{
Debug.Log("Collider hit something!");
}
public void setHitBox(hitBoxes val)
{
if(val != hitBoxes.clear)
{
localCollider.SetPath(0, colliders[(int)val].GetPath(0));
return;
}
localCollider.pathCount = 0;
}
}
Basic Workflow
For this example we'll be using Sprites and PolygonCollider2Ds.
Drag the sprites that need hit boxes into the scene. Attach a PolygonCollider2D component to each sprite. Click the Edit Collider button and fit the polygon to wherever you want the hit box for that frame. Make sure to do that for each sprite.
Next, attach the HitboxManager script to your actual character (Sprite) GameObject. This is the GameObject that will need to be doing the actual collision detection and animations.
This script will hold references to all of the colliders we just hand made. It already has room for two--currently named frame2 and frame3.
Create a public PolygonCollider2D variable for each sprite you customized earlier. Go back to the inspector and drag each sprite into the corresponding slot in the HitboxManager component. Make sure to also update the hitBoxes enum with each frame, and fill out the colliders array in Start().
Now the HitboxManager can use the collider info from each sprite. Our last step is to tell the manager when and what collider to use.
Animation Events
Note that the HitboxManager includes a setHitBox() function. This is what we will call from the animator to display or clear hit boxes as needed.
The character you're working on should already have the HitboxManager script attached, and this should also be the GameObject that handles the animating. Select that GameObject and open up the Animation editor.
From the clip dropdown, select the animation that needs the hit boxes we've been working on.
To add an event, right click above a frame and select "Add Animation Event". Choose setHitBox() from the function dropdown. Select the value that corresponds to the frame (and thus hit box) you want to enable with this animation event at this frame.
Go ahead and add a setHitBox() clear event somewhere near the end of your animation. This just resets the collider so your hit boxes don't stay forever.
That's it!
Test your scene out and watch the collider update in sync with your animation. To see the collider, make sure to have the GameObject selected while playing, and enable Gizmos in the top right of the Game view.
Want to see OnTriggerEnter2D() fire when your collider hits something? Create another game object that has a 2D collider on it, set Is Trigger to true, add a Rigidbody2D component and set Is Kinematic to true. Your trigger events should now fire whenever you hit this GameObject!
Cleanup: You can also disable all the sprites that you have in the scene you created earlier. Don't delete them though or the link to their collider info will be gone.
Enjoy these placeholder graphics as well.
This really helped out a big deal, was actually one of the biggest obstacles I was dealing with thank you very much for this.
@Noodles the Cat - when thanking or commenting, please add a comment. I've converted your answer to comment this time.
Could this be customized to accept box and circle colliders as well?
Absolutely. You could easily change each occurrence of PolygonCollider2D to BoxCollider2D or CircleCollider2D--as long as your collision type is consistent. This script could be modified to accept multiple types at once but would need some clever modification first. And witchcraft.
Your answer
Follow this Question
Related Questions
Remember animation frames when reloading model 1 Answer
Character won't play animation 8 Answers
Select frame for Animation 1 Answer
A quick question about animation frames 1 Answer
Need help with animation rewind 1 Answer