Search Unity

2D Hitboxes/Hurtboxes Based on Frame

Discussion in '2D' started by boxhallowed, Mar 24, 2016.

Thread Status:
Not open for further replies.
  1. ngrimesdev

    ngrimesdev

    Joined:
    Mar 22, 2016
    Posts:
    15
    Are you still going to put together an example project?
     
    G-Nimi likes this.
  2. ngrimesdev

    ngrimesdev

    Joined:
    Mar 22, 2016
    Posts:
    15
    Understood. Can't wait to see it. :)
     
  3. SVC-Games

    SVC-Games

    Joined:
    May 21, 2013
    Posts:
    137
  4. ngrimesdev

    ngrimesdev

    Joined:
    Mar 22, 2016
    Posts:
    15
    I've been working on a combo and hitstun system while waiting, it's coming along.
     
  5. SmashingSuccess

    SmashingSuccess

    Joined:
    Dec 14, 2014
    Posts:
    10
    The Britain, I have found a solution that works well for me, but I am unsure how much processing power it takes up.

    What I do is I have a prefabbed "attack hitboxes" object childed underneath the player. Then, I create subchildren for each attack, and then subchildren under each of those for each individual hitbox for each animation. Each hitbox subchild has a 2dpolygon trigger that are edited to match the specific frames of animation, a hitbox script, and and rigidbody 2d that doesn't do anything but keep things accurate.

    Inside the hitbox script there are variables for everything any individual frame might need; its damage, its attackID to keep 1 attack from hitting more than once and for allowing multihitting moves to occur, how much knockback it does, and how much hitstun it puts on the enemy, etc etc. It also registers whenever an enemy enters that collider and activates what that attack does. This makes it expandable to work with things like command grabs, normal grabs, super moves, you get the idea.

    Then, in the animator, I turn on and off the polygon triggers for each frame of the animation that they are needed/not needed.

    This should give you the level of control you are looking for and still be 99.9999% accurate as far as hitboxes actually hitting their targets go. If you want more info, let me know, and I'll get back to you when I can.
     
    Kaizen_Creed and theANMATOR2b like this.
  6. Gamingbir

    Gamingbir

    Joined:
    Apr 1, 2014
    Posts:
    197
    is there anything new development or tutorial on this topic? I am developing a similar project too
     
  7. Dokkanosaur

    Dokkanosaur

    Joined:
    Jul 18, 2017
    Posts:
    11
    Hey guys, just throwing in my experience on this issue.

    I'm currently working on my first big indie game, a 16-bit style ARPG [demo to come at PAX AUS ;) ] and I've basically built a solution to deal with this issue from scratch, basically because the standard unity animator can't answer basic questions like "what frame am I on?". I wanted the level of control that you'd see in something like Super Smash bros but for 2D sprites, so that was my target.

    The solution happens to be sort of similar to what SmashingSuccess detailed above, except I'm using a lot of custom classes and a custom editor to make it really really easy to set up:
    • I've created my own data files (derived from scriptableobject) that basically house a single animation as an array of frames (sprites) with their associated hitboxes / layers / properties etc. These files open in a custom unity editor I built that looks a bit like AfterEffects / Flash (preview up top, layers and timeline down below). I've scrapped the Unity animation editor for this solution entirely.
    • In the editor you can create layer groups like "physics", "hitboxes", "hurtboxes" etc that are templated in their behaviour. You then create individual hitboxes that live in layers and exist over multiple frames. Like Flash, you have "normal" frames, "key" frames and "empty" frames, which help minimise the amount of repetition / duplication you'd otherwise see between frames.
    • You can type in values for hitboxes in the custom editor or transform the box to suit with grab handles, visually, in the preview window. You can even add "SendMessage" strings to your gameobject to run custom functions (like triggering sounds) on a per-frame basis.
    • You attach your newly created asset to a gameobject of your choice that also needs a "sheet reader" component on it. The "sheet reader" works like the native "animator" component, except a bit more old-school. There's no animation flowchart, you just call "play(animation, framerate, looping);" and it'll play that animation.
    • Sheet reader sets the SpriteRenderer to the right frames on cue, creating and maintaining child objects that handle all of the collider information for each hitbox, updating the associated properties (damage, knockback etc) on each frame as you go.
    • I've also got a component on each object called "life" that handles the collision between objects and calculates damage, knockback, invincibility etc.

    I'm pretty proud of the solution so far... It takes like 60 seconds to go from dragging and dropping the sprite frames, create all the layers, draw the hitboxes, manipulate them over frames, add values. done.

    I'm actually thinking about forking it from my project and making it a standalone tool in the asset store. Here are some screenshots of it as it is right now. It works great for me but the UX is still a bit janky and I've got a long list of features I want to add before I'd call it a complete tool. Would anyone be interested in something like this?

     
    Last edited: Jul 18, 2017
  8. ZygoUgo

    ZygoUgo

    Joined:
    Jul 11, 2017
    Posts:
    63
    Looks great :)
     
  9. Joelforr

    Joelforr

    Joined:
    Sep 24, 2015
    Posts:
    2
    Hey Dokkanosaur, first time posting on the forum, but I'm really interested in the solution you implemented.

    I've been trying to break down the process, and I was wondering if you're okay with confirming some of thoughts or sharing some helpful resources. So here goes on how i think this is working:

    There is some sort of data file that holds a unity animation and breaks it down to an array of sprite images, which I would assume you pass in the unity editor?

    Based on the amount of sprites some sort of data structure is being created that holds and associates the sprite with HitBox Data. Maybe something like:
    Code (CSharp):
    1. public class FrameData{
    2. Sprite sprite;
    3. HitboxProperty groundCheck;
    4. HitboxProperty hurt;
    5. HitboxProperty hit;
    6. }
    7.  
    Now i think this is managed and manipulated by your custom editor, which is where I begin to get lost in terms of how this is being done through code. But I assume you control how many hit box properties you want to create here, as well as the type of the HitBox Property, how many colliders to create and their size. I'm not too familiar with editor code so I'm curious how this was accomplished.

    After compiling editor changes, what i'm assuming to be the editor script creates child objects to manage each saved property. Then during play mode the properties are switched out based on the current frame being played.

    Not entirely sure if I'm heading in the right direction, but any help on creating this sort of system would be greatly appreciated. Im working on a 2D game for my thesis project and I'd liked to create a hitbox system that easy to manipulate over frames.
     
  10. Dokkanosaur

    Dokkanosaur

    Joined:
    Jul 18, 2017
    Posts:
    11
    Hey there Joelforr,

    No problem. Yes, there's a data file I call a "box sheet" that's basically an array of sprite images. The data structure is something I'm working on getting right, but right now the solution I have is that each "sheet" has a list of Groups: hurt, physics, normal hit, fire effect hit, poison effect hit, whatever you want, they're just names. Each group has layers which represent one continuous hitbox over time.

    So in its most basic form, one Box Sheet has a List<Sprite> and a List<Group>. Each Group has a List<Layers> and each Layer has a List<Box>. Each Box has size, position, and frame status (keyframe, normal frame, empty). You can see it's not particularly elegant (because you'd think it would be better represented as like, a 3D array or something right?) but it works as a collection of lists for now.

    So anyway, of course, my custom editor creates and manages these files with the UI I posted above. This uses unity's very messy custom editor functionality. Once I save my data file, a "Box Sheet", I can play it in the scene using a component I created called a "Sheet Reader" (like the Animator component) that, as you suggest, just keeps track of the time and which frame should be played next. When a new frame comes up, it updates a series of child Gameobjects (created at runtime) which contain the collider data and are situated on relevant collision layers, specified by the Box Sheet.

    So if I have a character that has a run animation, that'll be saved in one Box Sheet file with maybe a Physics layer and a Hurt layer. I attach it to my character script and when it's time, I send that to the Sheet Reader component on my Gameobject which will cycle through frames, updating colliders within child objects called Physics and Hurt in time with each frame change.

    Make sense? It's a bit hard for me to read, maybe I'll make a video at some point. I really want to make this a solution people can download on the Asset Store but I'd need to see more interest first (I'm really busy right now >_< ) since it'll take time to polish into a usable tool.
     
  11. arrayofchar

    arrayofchar

    Joined:
    Nov 5, 2017
    Posts:
    3
    Hi Dokkanosaur

    I think the default animation editor works just fine, where you just add whatever property you want to transform in your current clip. This of course limits you to a static number of hitboxes, which should be good enough for performance optimization, and then you just apply the appropriate transforms to your colliders for each frame, including enable/disable additional hitboxes. Depending on how many gameObjects you create during runtime, it may not be much of a performance issue. But this method totally avoid creating objects during runtime. You just need to create child gameObjects that represents each layer of hitbox for your game character.
     
  12. Dokkanosaur

    Dokkanosaur

    Joined:
    Jul 18, 2017
    Posts:
    11
    Hey arrayofchar,

    What you describe is basically how I implemented it: enabling / disabling / updating existing colliders, with the exception that I allow the creation of new layers (objects) and new boxes (colliders) at runtime. During the scene, new sheets can be loaded into a gameobject which may use more / fewer layers (attacks might have Hit and Hurt boxes, while idle animations only have Hurt), so I create them when they're needed rather than try to pre-load things I might never need.

    I'm not sure the Unity animation system would have been a better solution. I was using it to begin with and there were a number of issues I had with it.
    • No easy way track simple information like "what frame is playing right now?"
    • Lots of convoluted functionality like lerped transitions that make sense for 3D but impede sprite-based animation.
    • Animator variables handling playback that create a communication gap between my script and the animation.
    • No easy way to "design" hitboxes over the animation frames.
     
  13. arrayofchar

    arrayofchar

    Joined:
    Nov 5, 2017
    Posts:
    3
    Dokkanosaur:

    You can use events in animation editor. I don't think I need to know which frame I'm on as long as I have the correct translation of collision boxes at the right frames, triggering events.

    The mecanim in Unity is an overkill for 2D sprite games, but it has everything that 2D sprite games need. If you don't use something, it shouldn't affect your performance in anyway just because it's a bigger system. May have more levels of references/calls because of inheritance but the effect should be miniscule.

    It's not as expedient as your custom editor interface, but it gets the job done, and it's not too inconvenient. You do it once for every character unless you have to change animation sprites. You can see your sprite in scene window, and you can see all the collision boxes you layout. I mean it's like 3 layers of collision boxes: physics (which you can just put it as a component for the gameobject, instead of contained in a child object like you have in your screenshot), hurtbox, hitbox.

    For me, I also need to categorize an animation into startup frames, active frames, and recovery frames. That I can do with events in animation editor.


    The-Britain:

    My guess for getting consistent framerates for fighting games is that you can do input detection in fixedUpdate which should guarantee consistent framerate. At least you get the input consistent, despite possible inconsistencies with rendering framerates.
     
    theANMATOR2b likes this.
  14. Joelforr

    Joelforr

    Joined:
    Sep 24, 2015
    Posts:
    2
    Hey Dokkanosaur,

    Thanks, that was a bit helpful. I'm still a little confused, but I'm sure it'll make a bit more sense once I try to implement the system instead of thinking about how it should work. A video would be awesome but if you plan on bringing this to the assets store I wouldn't want you to do something that would impede you accomplishing that
     
  15. Dokkanosaur

    Dokkanosaur

    Joined:
    Jul 18, 2017
    Posts:
    11
    If I were making a game where the hitboxes never needed to change shape (e.g. classic top-down zelda where everything is a square), then you're right, this tool isn't necessary. The sprites can be viewed in the scene. Colliders can be drawn in the scene... just put a square collider over your sprite and you're done. Need a sword? that's just one other square that pops in and out when the player hits a button.

    But for me, and I guess most others in this thread, we're looking to implement hitboxes that are dynamic to specific frames for higher resolution sprites. So now, potentially every frame, those hitboxes might need to change dimensions to match what the sprite is doing. Especially for fighting games this is critical. I have some animations with 20 frames in them, where the hitboxes on each layer change shape like 10 times. Drawing colliders in the scene on a per frame basis is not feasible.

     
  16. arrayofchar

    arrayofchar

    Joined:
    Nov 5, 2017
    Posts:
    3
    Unity already has frame by frame transform for any gameobject components for animations. The main idea is that transformation (especially translation and resizing, not including Quaterion rotation calculation) is less computation/memory intensive than creating gameobjects. If you use unique collider boxes for each frame, then it's quite memory hogging. I'm implementing a fighter hitbox mechanics. But with classic fighters, they only use a few hitboxes at most, as opposed to Skullgirls that create infinite number of hitboxes each frame. If you are only using a few, you can match the animation frame by frame with hitbox translation by those frames as well. You just use Add Property button in the Animation window to change your colliders. It's not as easy as your custom hitbox interface, but it gets the job done nonetheless. Since doing hitboxes is a miniscule part of the overall game project, the default mecanim isn't too bad of a choice in getting the job done.
     
    theANMATOR2b likes this.
  17. Kaizen_Creed

    Kaizen_Creed

    Joined:
    Dec 1, 2017
    Posts:
    2
    Hey I am working on a project and it close to completion when it comes to the codes I need to add into my game. Is there anyway I could contact you so you could walk me through the process so I could create a similar editor for hit detection? I just cannot seem to wrap my head around your explanation.Thank you for hearing me out, and I hope you'll be down to help me!
     
  18. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,699


    Hi, So you are actually instantiating Hit and Hurt Boxes, per frame??? Isn't that terrible for the CPU?
    Other than that tho, I am curious as to why you are not pooling them?
     
  19. waqas_haxhmi

    waqas_haxhmi

    Joined:
    Jun 15, 2016
    Posts:
    15
    Is there any example project ??
     
  20. killergoat72

    killergoat72

    Joined:
    Dec 30, 2015
    Posts:
    2
    I would be very interested in that asset.
     
  21. holliewillow

    holliewillow

    Joined:
    Jan 31, 2019
    Posts:
    1
    Myself as well, any any news on this Dokkanosaur?
     
Thread Status:
Not open for further replies.