Search Unity

Fighting Game Combos?

Discussion in 'Input System' started by JakHussain, Sep 3, 2019.

  1. JakHussain

    JakHussain

    Joined:
    Oct 20, 2016
    Posts:
    318
    So I've implemented a combo system previously with the old Input system, enums, input queues and a lot of headaches. It wasn't very extensible or easy to remap. I wanted to ask if anyone has tried something like this with the new input system, what parts of the system helped them and if there were any lessons learnt before I dive in.
     
    NeatWolf likes this.
  2. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    I've done this with the new input system + ECS, still working on refactoring my combo system to use ECS, but I have the Input core working.

    Here's what I've learned:
    • I haven't tried the remapping feature / example gui but from the APIs that are available and the fact they'll be releasing a uGUI rebinding example screen, this is the #1 thing the new input system brings to the table.
    • It's super easy to setup action maps that have bindings for various control schemes, and now it's very stable overall (I got in last year when a lot of things were in flux, I haven't had to rewrite much nu-Input related code since earlier this year, outside of taking advantage of newer features).
    • I was able to setup gamepad + keyboard versions of the same bindings fairly quickly using the "Control Schemes" feature of action maps.
    • I've found that for beat-em'-up/fighting game input, you may want to poll and track the value changes with your own history buffer at this point, which is what I've done. I may see how the documentation / samples evolve over time to accommodate this input style.
      • My action maps are setup as Value input type for the buttons, and I read from the action state using the InputAction.ReadValue<T>() API. This is a bit more discrete than you might need for other game types, but for Fight/Beats and customing timing logic (since ECS frame timing can't be properly locked to 60fps for sim and update, I have to tick the Input System manually to sync it properly with my ECS Input subsystems. It also avoids the overhead of delegate event calls, or delta events getting drowned out with high-frequency changes.
        • To add to the above point, you can get a lot of extra event call noise on some gamepad devices, such as PS4 pad on a PC. Man that thing is noisy. With the new ReadValue<T>() API for actions, I can just query my "move" action once a frame, but a user can rebind it if they want (say left-stick -> right stick for example)
      • Setting up multiple local players is a snap with the PlayerInputManager and PlayerInput components, but I did have to create my own prefabs and ECS conversion scripts and use the via Hybrid ECS. There's no good pure ECS solution for the Input System at all right now, but it seems like they'll start on that next year or the year after.
    • I have a dynamic buffer per-player that acts as that player's input buffer for combos to read from, Dpads are easy to read, I have some custom math to resolve stick to a dpad vector. If the dpad and stick are active I prefer the Dpad as my testing with XBOX One and a few other controllers shows that you can get more precise control and combo input with dpads. My current stick math is pretty good after several iterations now.
    • The earlier more event-driven versions of the code were way more complicated. I made a refactor a few months back based on a better understanding of fighting game input systems and I simplified it massively. The only actual state in the history buffer is several integers worth of status flags, and I avoid excessive eventing in the ECS layer, using the Hybrid adapter layer I wrote to insulate it.
    I'm currently working on adding some more robust test cases to my input framework and the combo checker code. I may open source part of this or make a Post-mortem for it in the coming weeks.
     
    Rene-Damm, thelebaron and NeatWolf like this.
  3. BindingForceDev

    BindingForceDev

    Joined:
    Aug 13, 2014
    Posts:
    40
    Yeah, I second the above response. I'm coding a beat-em-up/pvp fighting game and just keep a List of the inputs I receive. How you decide what to record, when to reset the buffer (my List), and how to interpret the list will be game specific. For instance, I actually record two Lists, one for actions and one for movement each of which contains enum values I have defined for them. I then have some logic to decide what the player is intending to input. If the action List contains say, jab, and the movement List contains say, forward, I'd interpret that as one action. Alternatively if the action List is, strike, and the movement List contains, down forward and up, I'd trigger the action for that combo. It gets confusing, but I like the performance and results so far. Again, every game will have different requirements and how and when you build your buffer system will be specific to your use case.