How to make a system to perform double tap directional inputs, similar to DMC, Bayonetta and other action games.

Hello I’m setting up a system to test a couple things for an idea I have in mind, so I’m trying to replicate a standard Devil May Cry esque base to branch off from. Issue is, I cannot figure how to make the input system to detect how to perform the “Stinger” type of move. This move is done by quickly double tapping in a direction then pressing the attack button.
Normally I want this to be able to work by using the camera as a reference of the direction, but able to withstand possible camera sway or angle changes that might be caused by natural in game movement.

Currently I tried a method that stored the last 2 directions input and attempted to compare them to see if they were performed in the overall same direction, but it wasn’t any good, so I’d like to hear some opinions for your own takes on this system.

are you using Enhance Input (engine Version 4.27 or later and forced in 5.2 or later) or are you using the project settings method (engine version 5.1 or earlier)? (I will be assuming Enhanced Input, but different steps would need to be followed for the Project Setting method)

is this going to be using like a joystick or like directional keys?

the “easiest way” that includes all possible inputs is that you will want to maintain the last N inputs from the player (for the enhanced Input system what is typically used for directional input returns a Vector2<float>, and a directional pad has 3 potential states {-1. 0. 1} as outputs while a joystick can be any value on the bounds of {-1, 1} for each piece to the Vector2<float>)

typically for movement keys we only care about when it is giving a non-Zero value, but if this is supposed to be like
Player pushes Left -> player neutrals direction -> Player Pushes Left
then you will want to bind to Completed and Canceled as signifying the “released” state

to compare the last few inputs together I would suggest creating some kind of

enum EInputState{
None, Left, Up_Left, Up, Up_Right, Right, Right_Down, Down, Left_Down,
// you may want to list the other input keys you want to be queueing
};

the directional inputs are probably the trickiest to figure out, but you want to take the Vector2 and check each the X (Left/Right) and the Y (Up/Down or Back/forward) to see what direction is being used something like

tempD1;
if( input.y > 0.01f ){  tempD1 = Up; }
else if( input.y < -0.01f ) { tempD1 = Down; }
else { tempD1 = None; }
tempD2;
if( input.x > 0.01f ){ tempD2 = Right; }
else if ( input.x < -0.01f ) { tempD2 = Left; }
else { tempD2 = None; }
curDirection
if( (tempD1 == None) && (tempD2 == Left) ) { curDirection = Left; }
else if ( tempD1 == None ) && (tempD2 == Right ) ) { curDirection = Right; }
else if ( tempD1 == Up ) && (tempD2 == None ) ) { curDirection = Up; }
else if ( tempD1 == Down ) && (tempD2 == None ) ) { curDirection = Down; }
...
else { curDirection = None; }


this will be triggered once per frame (faster then the average human response time) so you will probably be tracking whenever there is a change, rather then adding each and every one to like a Queue.

then create like an Actor Component where we are going to be faking a queue ( in C++ a TQueue is an already available Container, but this is not immediately available to blueprints though this is a fundamental Data Structure in CompSci ) if you need additional help on making a queue then I can elaborate further.

Sounds about right to me. So you used the Dot Product and queried whether the resulting float was in range?

This move is done by quickly double tapping in a direction then pressing the attack button.

I’d pair the dot result with the Enhanced Input’s Tap or Chorded Action triggers. There’s also Combo (Beta) but never used it - not sure if it works or makes sense here.

Hey, I am using the Enhanced Input System for this method. Sorry, but the method you’re proposing seems to focus on cardinal directions, when I want the analog direction of the joystick to be a factor for the input…

Besides, I’d it’s using canceled and complete events to trigger, but for a system to be truly like DMC, the event must be on input start (If you double tap, and you press an attack button before you let go of the stick the second time you tilt it, you get the move still. This is common in games with movement inputs in order to make them cleaner and more comfortable to use.

the cardinal directions is so that it can grab the up down left right, but then it is combined to make 8 directional. it would need additional work for say perfect quarter circle/half circle inputs, but it is doable.

the actual movement vector will still be mapped to the full 360 but the recorded is in 8 directions. if you need the absolute Vector then it still exists and can be exact (or as close as floating point approximation will get you)

I use Canceled/Completed to register when the input stops (the button direction is returned to a neutral state
for example if the user hits Button_B->release->Button_B you need to connect into Canceled/Completed to get the release part.

I’m not very sure how to use the dot product, admitedly. What I did was very sloppy, so it wouldn’t surprise me if I did it completely wrong… If you have your own take on it, I’d be happy to see.

The way I tried this was by modifiying the vector values of the 2nd tild to create the range, and comparing it to the 1st. Issue is, it doesn’t work at all and I can’t tell why.

As for the second part, I don’t know much about chorded action or its applicaitons. At first I tried to use the Combo trigger, but couldn’t figure it out.

I’m not super sure about it… Specially if, for instance, I want the character to turn in the direction instantly to override character turning speed that occurs with nomal movement.
And you say your system also needs to use Canceled / Completed to work? It doesn’t seem ideal for what I need.

Hey there… This is an update from last time. I managed some sort of system using the Dot Product as you suggested, and it’s giving some decent results. Now I’m working around to make a system that allows to read 2 inputs without needing to fully return the stick to neutral, it’s a bit tricky but I’ll probably get to it.

Also, how do you mean to pair the EIS tap / chorded action with the Dot result? I can’t imagine how to do that.

• when you get input the first time, store the direction of the camera (it’s camera based, right?)

• when you get input again, dot product the stored direction with the camera’s direction

• the closer to 1 you are, the more precisely both inputs aligned

Not at the PC but EIS does handle it afair.

Disclaimer: never played DMC and don’t know what Stinger is. Sounds cool, though! Hope I am not confusing things!

Hey! No worries, the actual Stinger move isn’t what I’m after, but the input of double tapping the stick in a direction to perform a different move. This has the application of multiplying the amount of possible actions each button can perform.

Right now I’m havign a dot tolerance trenshold of .8 which yields good results, still need to add the store direction of the camera bit you say, though. So far, I feel I’m finally cracking it!

1 Like

Not at the PC but EIS does handle it afair.

Almost forgot! Regarding this, how could you do it with EIS? Right now I have a gate that resets based on stick axis value to store stick direction, but if you have a built in method I’d love a more in depth explanation