How can I make a random sequence of keys to press?

Hi, there! So, I want the player to press a sequence of keys that is randomly generated by the game.
In my case, I want the sequence to be with 6 keys and only with the arrow keys. What I mean is like:
Randomly generates sequence > The sequence is UP, UP, DOWN, LEFT, UP, RIGHT > The player needs to do this sequence.
What I tried so far was making this:

public KeyCode first, second, third, fourth, fifth, sixth;
    private KeyCode[] sequence = new KeyCode[]
    {
        first,
        second,
        third,
        fourth,
        fifth,
        sixth
    };
    private int sequencePattern;

    void Start () {

    }
   
    void Update () {

        float one = Random.Range (0, 4);
        float two = Random.Range (0, 4);
        float three = Random.Range (0, 4);
        float four = Random.Range (0, 4);
        float five = Random.Range (0, 4);
        float six = Random.Range (0, 4);

        if (one == 0) {
            first = KeyCode.UpArrow;
        } else if (one == 1) {
            first = KeyCode.DownArrow;
        } else if (one == 2) {
            first = KeyCode.LeftArrow;
        } else if (one == 3) {
            first = KeyCode.RightArrow;
        }

        if (two == 0) {
            second = KeyCode.UpArrow;
        } else if (two == 1) {
            second = KeyCode.DownArrow;
        } else if (two == 2) {
            second = KeyCode.LeftArrow;
        } else if (two == 3) {
            second = KeyCode.RightArrow;
        }

        if (three == 0) {
            third = KeyCode.UpArrow;
        } else if (three == 1) {
            third = KeyCode.DownArrow;
        } else if (three == 2) {
            third = KeyCode.LeftArrow;
        } else if (three == 3) {
            third = KeyCode.RightArrow;
        }

        if (four == 0) {
            fourth = KeyCode.UpArrow;
        } else if (four == 1) {
            fourth = KeyCode.DownArrow;
        } else if (four == 2) {
            fourth = KeyCode.LeftArrow;
        } else if (four == 3) {
            fourth = KeyCode.RightArrow;
        }

        if (five == 0) {
            fifth = KeyCode.UpArrow;
        } else if (five == 1) {
            fifth = KeyCode.DownArrow;
        } else if (five == 2) {
            fifth = KeyCode.LeftArrow;
        } else if (five == 3) {
            fifth = KeyCode.RightArrow;
        }

        if (six == 0) {
            sixth = KeyCode.UpArrow;
        } else if (six == 1) {
            sixth = KeyCode.DownArrow;
        } else if (six == 2) {
            sixth = KeyCode.LeftArrow;
        } else if (six == 3) {
            sixth = KeyCode.RightArrow;
        }
       
    }
}

And I keep receiving the error “A field initializer cannot reference the nonstatic field, method, or property NameOfTheClass.first', NameOfTheClass.second’” and so on.

Thanks ^^

In regards to the error you’re getting, the issue is that this:

    private KeyCode[] sequence = new KeyCode[]
    {
        first,
        second,
        third,
        fourth,
        fifth,
        sixth
    };

Is not allowed to access these from the class scope (not inside a method):

public KeyCode first, second, third, fourth, fifth, sixth;

In order to assign sequence to be a sequence of the six keycodes, you would need to create that array in Start (or some other method).

However, this won’t solve your overall problem. KeyCode is an enum. Enums are passed by value. If you created an array and put first in it for example, it would not be putting the variable first in the array, it would be putting the value of first into the array. Meaning that if first gets changed later, the array value won’t update to match it. So with that logic, you would need to assign the generated keys to the array every time you regenerate them (and putting that logic in Update seems like a bad idea unless you want to generate a new sequence every frame).

I wouldn’t approach this problem from such a hardcoded angle. I would probably just do something like this:

public KeyCode[] validSequenceKeys = new [] {
    KeyCode.UpArrow,
    KeyCode.RightArrow,
    KeyCode.DownArrow,
    KeyCode.LeftArrow
};

KeyCode[] GenerateSequence ( int length = 6 ) {
    KeyCode[] sequence = new KeyCode[ length ];

    for( int i = 0; i < length; i++ ) {
        var key = validSequenceKeys[ Random.Range( 0, validSequenceKeys.Length ) ];
        sequence[ i ] = key;
    }

    return sequence;
}
1 Like

Got it, thanks a lot!

I’m pretty new to unity and the code is helpful but any help on how to implement it to actually get a display would be really appreciated

Create a Text UI element and make the key name to be part of the text displayed

I get these errors:
Assets\Arrows.cs(5,18): error CS0116: A namespace cannot directly contain members such as fields or methods
Assets\Arrows.cs(12,11): error CS0116: A namespace cannot directly contain members such as fields or methods
Can you tell me how I can fix these or what I’m doing wrong

You need to put the functions and variables inside a class.

If this is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public KeyCode[ ] validSequenceKeys = new[ ] {
KeyCode.UpArrow,
KeyCode.RightArrow,
KeyCode.DownArrow,
KeyCode.LeftArrow
};
KeyCode[ ] GenerateSequence(int length = 6) {
KeyCode[ ] sequence = new KeyCode[length];
for (int i = 0; i < length; i++) {
var key = validSequenceKeys[Random.Range(0, validSequenceKeys.Length)];
sequence = key;
}
return sequence;
}
What is it exactly that I need to add or change, because I tried changing “public” to “public class” but that just gave me 15 me errors, I’m pretty bad at this if no one can already tell.

What he’s saying is you nuked part of the necessary code when you pasted that in. Open up a new script and start over, taking care not to paste over top of anything that’s already there.

that still gives the same error, could it be anything else?

@vipergabe You will need to broadly familiarize yourself with C# syntax before you can do anything but copy other people’s code (and even then you will run into problems, as you are experiencing). Unlike human languages, it matters if you botch the grammar even a little bit on computer languages. Computers need your code to be exactly right for it to work – otherwise it will break. Check out something like this, which will give you a basic introduction into how C# syntax works in the context of Unity: https://www.youtube.com/watch/nWkUutm7Kus There’s also a unity wiki page with more information here: http://wiki.unity3d.com/index.php?title=The_Absolute_Beginner’s_Guide_to_Unity

Additionally, keep searching for information on how to write C# outside the context of Unity. Microsoft has a lot of documentation on this topic: Programming Concepts - C# | Microsoft Learn

Every script starts with

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
    
    }

    // Update is called once per frame
    void Update()
    {
    
    }
}

Your code is missing basically all of that. In general, variables go after public class {, before void start.
Operational code goes inside start or updates’ brackets, or maybe a different method that isn’t normally there by default.
At this stage you should not replace any of it.

I’d strongly strongly strongly recommend following the Unity Learn essentials & beginner pathways. It has you work on your own project as you learn the basics.

Then

1 Like