Hi. So I have been searching for this for a long time now, but the questions that are asked about key combos are not the kind of key combos that I want. So I need that when I press a key, like numpad1 then release that key, then press like numpad2 and then numpad1 and then I do the code. So here is the most basic fail that I have come up with…
using UnityEngine;
using System.Collections;
public class Jutsus : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
if(Input.GetKey(KeyCode.J)){
if (Input.GetKeyDown (KeyCode.Keypad1)) {
if (Input.GetKeyDown (KeyCode.Keypad2)) {
if (Input.GetKeyDown (KeyCode.Keypad1)) {
print ("Hi!");
}
}
}
}
}
}
GetKeyDown is only true for the exact frame in which the key is first pressed, and Update is always run in a single frame. So if you nest your if statements that way, they must all be true at the same time.
To capture a key combo, you will have to track its state across frames. You’ll want to be watching for the next key, and then when that one comes, you watch for the one after that.You could do that with a series of bool’s and a bunch of if statements, but there’s a better way than that: An array and index.
public KeyCode[] combo;
public int currentIndex = 0;
void Update() {
if (currentIndex < combo.Length) {
if (Input.GetKeyDown(combo[currentIndex]) ) {
currentIndex++;
}
}
else {
Debug.Log("Combo done.");
}
}
Now you set up your combo in the inspector. Bonus: this is reusable with multiple different objects and combos for different functions.
I guess you’re designing a combo move system? If so I’d use state machines. So each Update() you don’t have to do anything more complicated than calling an Execute() method on the (dynamically changing) current state for input.
It works great! But one thing… If I try to play a sound with: sound.Play(); It messes it up. It tries to play it but it is updating every frame so it can’t play. Can you help me with that? Thanks
I’m guessing you’re playing it in Update in the else block?
You’ll want to reset the currentIndex back to zero after doing whatever the combo does.
Also, note that the current code will check for doing the combo, but not whether other keys were pressed in the process. For example, if the combo is “A,B,C” then the sequence “A,Z,Q,C,X,B,Y,T,U,A,C” successfully completes it.
Checking for incorrect keys in the middle of the combo is pretty easy - if Input.anyKeyDown is true, and Input.GetKeyDown for the current key isn’t, then that’s a fail.
For something like A,B,C,D != A,B,C, you’d just have to decide how long after the last key of the combo to wait, and fail if anything else is entered during that time. However, that would mean the action triggered by the combo doesn’t occur until after that delay either. If you have a way to cancel the action after it starts, that would give a smoother experience.