multiple player vs enemy hitbox / hurtbox : Hit detection best practice?

Welcome to our brand new Clickteam Community Hub! We hope you will enjoy using the new features, which we will be further expanding in the coming months.

A few features including Passport are unavailable initially whilst we monitor stability of the new platform, we hope to bring these online very soon. Small issues will crop up following the import from our old system, including some message formatting, translation accuracy and other things.

Thank you for your patience whilst we've worked on this and we look forward to more exciting community developments soon!

Clickteam.
  • Hi !

    I'm working on a 2d platformer with beat'em up / fighting mechanics and I would like to have the community's feedback on how to best handle Hit Detection.

    A bit of background :I have one player and multiple instances of the same enemy active object. Each enemy has a Hurt Box active obj linked to him. This Hurt Box is used for hit detection.
    The player has several attack animations which trigger the creation of a Hit Box active obj which, when colliding which enemy hurtboxes, triggers their respective "get hit" animation.
    This system is very similar to what is done in 2d fighting games.

    The issue is that if one specific player hitbox overlaps several different enemy's hurtboxes, I need them each to register the collision only once.
    Obviously, the player's hitbox shall remain active for x number of frames and shall not be destroyed upon collision.

    With another programming language, I'll simply append the enemy's hurtbox Fixed value to a player hitbox "hit_registration" list, and check during overlap test that the hurtbox's Id is not already in that list.


    I was thinking of doing this using a alterable string on the hitbox and add to it the fixed value of each hurtbox it collides against (which is essentially doing what I described above but with a string instead of a proper list) but string search are not really fast and optimized... Maybe someone has a better idea for this...?

    Thanks a lot !

  • Im not sure if you've tried this or if it would be usable in this style of game, but have you tried doing away with the hitboxes altogether? I would try that, and add a Qualifier to the enemies, that way you don't have to worry about more objects/sensors etc following the enemies correctly. Then just make it so that when the player animation for hit, whichever they are, are overlapping the group.enemy then they play their hurt animations?

    Developer/Composer :

    Vamprotector

    Castlevania Chronicles 2 - Simon's Quest

    Castlevania Chronicles 3 - Dracula's Curse

  • Hi warmachine,

    Thanks for the feedback. The whole point of the hitbox / hurtbox system is to have precise collision detection: if i do a simple overlap test on an active (or a group) I cannot "exclude" certain parts of the sprite from the collision detection. For example, i want the extend arm of the play to cause damage (and get hit animation) but not the player's legs and reciprocally only the body section of the enemy should be hittable and not its tail. This is a random example but it should be manageable on an animation per animation basis. I'm absolutely positive that hitboxes and hurtboxes are the right way to go as this is exactly how old school and modern 2d fighters work.

    Regardless, the thing I'm trying to optimize is not collision detection in general but specifically registering multiple collisions from one hitbox to several hurtboxes over several frames and scoping which hurtbox has already collided with the hitbox to avoid loops. In that regard, I'm not sure how your solution would work but maybe I'm missing something? Anyways thanks for the shared knowledge !

    Cheers

  • I'm currently working on a fighting game that uses precise collision detection: Please login to see this link.

    I use collision masks instead of hit / hurt boxes since my game is more like Karate Champ than Street Fighter, but the concept is pretty similar regardless. I use a flag (or an alterable value if I want to determine different states) to stop infinite looping.

    So your code would go something like:

    Player 1 Hitbox collides with Enemy 1 Hurtbox
    + Flag 1 of Enemy 1 Hurtbox = 0 -------> Set Flag 1 of Enemy 1 Hurtbox to 1, Start hit/taking damage animation for Enemy 1 or whatever else you want to do

    If you plan on having a lot of enemies at once you might want to look into object scoping to pair up hit/hurt boxes with each instance of the enemy. Good article here: Please login to see this link.

  • Try to check for enemy overlapping hitbox instead of hitbox overlapping enemy. Only allow an enemy to be hit if their "hit" flag is OFF, and set it ON as soon as they overlap the player's attack hitbox. This can be turned off at a later time, like after their invincibility frames have run out for example.

    Best person at writing incomprehensible posts. Edits are a regularity.

  • Hi Graeme2408 and casleziro !

    First of all, thanks for taking the time to answer. The solution suggested by both of you (using a flag on enemies to prevent looping) is what I initially did in previous projects, and it works well to some extent, but it also has its limitations: the flag turns the enemy invinciblr for a set amount of frames, which is good to avoid registering hit detection the same hitbox but could show its limits in at least two instances:

    - if a player attack has a hitbox overlapping the enemy and that hitbox is active for more time than the invincibility, the attack will be registeeed twice. And I can deativate the hitbox upon collision otherwise other enemy will not get hit by it.
    - if another attack collides with the enemy right after the first one (which set the enemy invincibility flag on for a short period of time), it will not register.

    One might think that I'm being overly cautious and thinking about very rare cases, but my experience tells me that if I don't take them into account now, they will turn out to be real annoyances in the future which will force me to use workarounds. Besides, I'm trying to build the most flexible system right from the start, to no restrict myself in the future when designing the various attacks and their properties.

    Thanks for the help, I guess I'll try out my initial solution and resort to a simple flag mechanic if I really can't make it work or if performances are really low.

    Cheers !

  • If you make the hitbox appear only at point of contact it won't be active for more time than the invincibility frames, i.e. enemy taking damage animation frames.
    For the instance of a second attack not registering, you could either ensure the player attack animations have more frames than the enemy taking damage animations or else put a very slight delay between each attack.
    I prefer the first solution, e.g: If the player had a punch followed by a kick, you have frames where the punching arm extends (say 3 frames), point of contact at fist on full extension (frame 4). At this point when a hit is registered you start enemy animations showing taking damage (say 5 frames). The player's attacking arm withdraws (3 frames) and the second attack (kick) starts (3 frames).
    You won't ever miss a second attack landing as the time or frames of animations between the first attack ending and the second attack reaching point of contact is 6 frames while the invincibility of the enemy only ever lasts 5 frames while the getting hit animation plays.
    I'm probably not explaining this very well but I hope you can follow what I mean!

    Edited 2 times, last by Graeme2408 (June 10, 2019 at 1:43 AM).

  • How many attacks and combos are there? Can you post an example mfa OR a video of how your system works?

    If there are only a few attacks total you can give each attack an id (ie: Hit 1 = ID 1, Hit 2 = ID2, Hit 3 = ID3.) Apply said ID to the hurtbox your'e colliding with and perform your collision events only if the ID that's touching the hurtbox differs the ID stored in the hurtbox. Much faster and more efficient. The only thing you have to do is clear ID from the enemy on either an invincibility timer OR when your player is no longer using said attack.

  • Tldr: I appreciate your input and ideas. I believe I have studied and thought enough about this to know that using a “hit registration list” is the right way to go. The question was more how can I optimize this technically since “list” is not a native value type associated to active objects in CF2.5.


    Let me describe a little bit how the system work. I apologize in advance if this is messy, I’m not sure to be able to properly explain things.


    * For the purpose of explanation, let's forget for a moment that Player and Enemies are separated objects. The idea behind this engine is that it is as generic as possible to ensure that potentially any instance in the game could generate a “hitbox” and have a “hurtbox” attached to it, which implies that hit registration must be generic and cover many different cases. It is heavily influenced by how 2d fighters work with what is commonly called "frame data".


    * Let’s call a “hurtbox” a zone in space attached to a given object which is used to know if that object was hit by an incoming attack. There is only one “hurtbox” active, and it’s linked to possibly any object using the Fixed Value as an identifier.


    * Let’s call a “hitbox” a zone in space emitted by a given object (usually physically bound to it) which is used to store attack properties of the emitter (x/y translation upon impact / hit animation to trigger / damage amount / hit stun amount / elemental property, ...) . I do not want to determine in advance how many attacks there will be and how they work. These properties are stored in a config file and grouped under a specific hitbox ID. One given hitbox could be “single hit” or “multi hit”. This determines whether it can hit multiple times during its “active frame” time or only once. Of course, when I say “once” or “multiple”, I’m referring to hit registration on one specific “hurtbox” (or hittable object, if you will).


    “hitbox” and “hurtbox” are visually rendered in my project exactly in the same way they are in Street Fighter 3, for example. Just colored square active objects, which are invisible (they work as collision mask).


    * Let's call "Attacker" any object that can generate a "hitbox". It could be the main character, an enemy, a projectile (a bullet, a fire ball, an explosion ...), an environmental hazard (flames, thunder, etc). The Attacker has one or several attack animations. These animations have the usual "startup frames" (before the attack can do anything), the "active frames" (the time during which the attack can hit) and "recovery frames". Attackers could be players, enemies, environment, anything.


    * During the first frame of the attacker’s "active frames", the hitbox active object is created and an ID is dynamically assigned to it (based on animation properties). The hitbox remains until the last “active frame”, then it is destroyed.

    * During this time, if a “hitbox” collides with any “hurtbox”, it checks whether hit can be registered and if so, it impacts the owner of the corresponding hurtbox (x/y position, life, etc).

    * To avoid a “hitbox” registering collision on the “hurtbox” of the attacker, I’m using the Fixed value of the attacker as the “owner_id”. Simply put, it the owner_id of the hitbox is the same as the owner_id of the hurtbox, hit will NOT register.


    * Upon collision, the “hitbox” could still be active for some time but the hurtbox touched should not register collision from this specific hitbox (but could be touched by another one overlapping right after). In this regard, the “invincibility flag” is not a suitable solution because there could be different hitboxes (from different attackers) hitting the same hurtbox in a small time frame and I want to ensure all hit register.

    As to storing the “last_hitbox_id” on the hurtbox upon collision, this could work in most cases, but it would not work for “multi hit” hitboxes as the first collision registration would cause the following ones to be ignored.

    EDIT : after re-reading the solution suggested by GamesterX23, i think i'll try this as it can probably handle 95% of the cases if not more. I'm looking to do something that work 100% of the time but it's probably just an overkill...


    The solution I have in mind (and I’m pretty sure is the only one which covers 100% of the cases in my current system) is to store on the “hitbox” the Fixed Values of the hurtbox it collided with within a list, and check upon collision between hit box and hurt box that the Fixed value of the hurt box is not yet in the “hit registration list “ of the hit box it collided with. This forces me to do look ups in the list since I have to use a string and parse it (which is definitely not a fast operation for the processor). For the case of “multi hit” hitboxes, I can simply clear the list whenever this hit box can hit anything again.


    I hope the above makes it clearer and that you now understand what I want to achieve and how I’m planning on doing it.


    It would be complex for me to submit a mfa example of this collision registration engine as it is currently very intricate and there are lots of cross references to other objects within it. Eventually, this is something I’d like to share with the community !


    Cheers

    Edited once, last by malibumanjp (June 11, 2019 at 1:47 PM).

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!