- Home /
Waiting for several key presses
I'm making a game where you have to press the right keys before the game goes on. But the amount of keys to press is random. How can I check if a random (different every time the function is called) amount of specific keys are pressed at the same time?
Edit: To give you guys a better representation of what it needs to do: I'm making a finger trainer for rhythm games like the above. Instead of the notes falling down, they just appear until you press all the keys corresponding to the notes. This way, users will learn all the combinations without stress. The user can decide the amount of notes that spawn simultaneously and the amount of keys (positions where notes can spawn). Because of this, I don't know how many keys the user has to press.
Here's my code:
New code in the answers!
The game is still in a very early state. Users will be able to choose the keybinds and the appearance of the game will change corresponding to the amount of keys later on. But this should show my general ideal and why it doesn't work...
Thanks in advance, KillBottt
Answer by xxmariofer · Jan 16, 2019 at 01:55 PM
Any key posible? i would suggest creating a list with the keycodes that the user can press and then doing something like this where keys is the list of posible pressed keys:
int numberOfKeys = 0;
foreach(KeyCode key in keys)
{
if(Input.GetKeyDown(key))
{
numberOfKeys++;
}
}
if(numberOfKeys == THE_RANDOM_NUMBER)
{
Debug.Log("SUCCESS");
}
They have to be specific keys. I can't just use == here because I don't know how many there are. I used a switch statement because the number of keys are between 1 and 10, but that's a lot of code, it's hard coded and the success rate \ performance is bad.
Thats why you can create a serializefield or public list, so you can assign the keycodes that can be pressed in the inspector, and you can use if(numberOf$$anonymous$$eys == Random.Range(1, 10)) for making sure the numberOf$$anonymous$$eys is the same as the random number between 1 and 10.
Create [Serializefield]private list keys; and assign it in inspector
I suppose the game draws which keys should be pressed. You could make a list of keys that should be pressed and then each time when user press a key, check if key is on the list. If yes, increase the number and e.g. remove the desired key from the list so you won't get the same key marked twice as correct.
we need some extra explanation of how the game is designed, you always press the same keys? like always have to press a -b - c .... or they change at runtime? if they are the same my solution is fine, if they are dynamic @ilusja solution should work for you.
Answer by gamersfunnl · Jan 17, 2019 at 10:52 AM
With the help of @xxmariofer and @ilusja I managed to make it work most of the time. My code now looks like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
public class NoteGenerator : MonoBehaviour
{
//amount of keys (places where notes can spawn \ keybinds)
public int keyAmount;
//amount of notes that spawn simultaneously
public int noteAmount;
//the sprites I call notes
public GameObject[] notes;
//the keys corresponding to the notes (e.g. if notes[0] is active, keybinds[0] should be pressed)
public KeyCode[] keyBinds;
public Text KeysBeingPressed;
List<KeyCode> keysToPress = new List<KeyCode>();
List<int> randomNumbers = new List<int>();
int rightKeysPressed = 0;
//check makes sure that the code to check if the right keys are pressed in Update() is only read, when the preperation is done
bool check = false;
public void start()
{
//randomNumbers gets filled with numbers counting up from 0 (0,1,2,3,...) untill its the same size as keyAmount
for (int i = 0; i < keyAmount; i++)
{
randomNumbers.Add(i);
}
mainGame();
}
void mainGame()
{
//randomNumbers gets scrambled
for (int i = 0; i < randomNumbers.Count; i++)
{
int temp = randomNumbers[i];
int randomIndex = Random.Range(i, randomNumbers.Count);
randomNumbers[i] = randomNumbers[randomIndex];
randomNumbers[randomIndex] = temp;
}
//noteAmount of notes get activated (which note is chosen by noteAmount indexes of randomNumbers)
//the keys corresponing to the notes that got set active are stored
//these are the keys that have to be pressed by the user
for (int i = 0; i < noteAmount; i++)
{
notes[randomNumbers[i]].SetActive(true);
keysToPress.Add(keyBinds[randomNumbers[i]]);
}
check = true;
}
void Update()
{
if (check)
{
//the program check the input untill all the right keys have been pressed
if (rightKeysPressed != keysToPress.Count)
{
foreach (KeyCode key in keysToPress)
{
if (Input.GetKeyDown(key))
{
rightKeysPressed++;
}
}
}
//once all the keys have been pressed, the notes get set inactive again and some variables get reset
else
{
for (int i = 0; i < noteAmount; i++)
{
notes[randomNumbers[i]].SetActive(false);
}
rightKeysPressed = 0;
keysToPress.Clear();
check = false;
//then, the process starts again
mainGame();
}
}
//visualization of the keys being pressed (for testing purposes atm)
if (Input.inputString != "")
{
KeysBeingPressed.text = Input.inputString;
}
}
}
It normally goes very smoothly until it gets stuck at one note combination (always a different one): https://www.youtube.com/watch?v=suXTN6L9Yxc&feature=youtu.be Does anyone know why this happens? I'm certain I'm pressing the right keys! Edit: Should I make a new post for this question?
noreAmount is the number of notes that you spawn each round? but you dont modify it right? its always 3? also use keysToPress.Clear(); for removing the keys rather than create a new list
Yes, I'll make an option to choose how many notes the user wants to spawn (1-10 or random) later on. But until I get the base down I'll leave it like this. I basically make a list counting up, scramble it, and use the first few indexes to choose which key\note combination should be used. Then the program waits for the keys to be pressed, resets, and starts again.
i think i found the bug, you cant don this:
int randomIndex = Random.Range(i, randomNumbers.Count);
and should be
int randomIndex = Random.Range(i, randomNumbers.Count - 1);
since both max and $$anonymous$$ are inclusive
Use Start(), not start(), also $$anonymous$$ainGame(), not mainGame(). After watching this video few times and investigating your code, I don't really know what you're trying to achieve, sorry. What are the letters shown under Q W E R V?
Your answer
Follow this Question
Related Questions
Key down, to edit property 1 Answer
While Button Pressed 3 Answers
make Update display/animate iterations of While(i<20)loop? 2 Answers
while loop not looping 2 Answers