Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Logic for chaining attacks into combos

Discussion in 'Scripting' started by Sendatsu_Yoshimitsu, Nov 24, 2014.

  1. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    So I've finally gotten started on the melee component of my game: punch someone once, twice, thrice, and so forth until they or you keel over. I'm taking a lot of inspiration from Godhand, and allowing the player to essentially fill each slot in their combo chain with one of multiple techniques they have available. Where I'm getting stuck is on how to actually handle chaining attacks together. The rough framework I've worked already is pretty simple: every single attack is quantified in some Attack() class with a minima of data: name, range, damage, and animation. Alongside that, there's some int comboNumber that remembers how many attacks into the combo chain you are. The player has some List<Attack> containing every combo in their chain, and every time the player hits the attack key, you simply run a function ExecuteAttack(attackList[comboNumber]), which increments comboNumber by 1 and runs the next attack.

    This looks good on paper, but there are a couple of questions it raises that I can't figure out:

    1) How do you handle chaining attacks together within a window? E.g. if the player keys the next input in within 0.35 seconds of the last attack, it chains into a combo. Any longer and the combo resets.

    2) Linked to this, how do you handle button-mashing? If the character has three 0.5-second attacks, and the player mashes the attack button ten times over two seconds, I want the character to smoothly execute the three attacks in his combo and then reset.

    3) On a slightly more complex note, how do games with multiple buttons handle variable combinations, e.g. punch + punch = uppercut, punch + kick = spiral kick? Do they simply have the input manager count up the keys and listen for a sequence that constitutes a known combo?
     
  2. ErikElgerot

    ErikElgerot

    Joined:
    Nov 24, 2014
    Posts:
    11
    1) Simplest way to do this would be to store the time of the attack. That way, you can check the time of the last attack at the start of the attack function to see if you need to reset the combo or not.

    2) For button mashing, giving attacks a windup and cooldown (before and after) would probably be a good starting point? It's a good thing to have for your attacks anyway (since many attacks will have a short period before or after when they're not in "damage" mode.

    3) I'd say it depends on the depth of your combos (if you only have "punch" and "kick" and no combo is deeper than three hits, you've only got at most eight combinations anyway and it might be fine just to check for each sequence manually, otherwise you could consider doing something like a "combo tree".
    So you can store at what point in the tree you are, and then have it branch for possible combo progress from that point - if you try to branch off somewhere it doesn't have a leaf (so it isn't a valid combo), it just ends the combo there.

    This is just off the top of my head (and from doing a similar project myself at the moment), so there may be errors and/or poor design. =)
     
  3. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    Oh that's great, checking against Time.time is incredibly efficient and the combo tree is something I never would've thought of, thank you!!

    Cooldown and Windup is a great idea as well, I just mocked this up and right now I'm setting a nextAttack float to Time.Time + Cooldown, and I wonder if it wouldn't be simpler just to use Time.time plus the animation's duration, I'll try it out and post back :)
     
    ErikElgerot likes this.