Using Random.Range to pick a random value out of an enum

Hey Guys,

Fairly basic question, but I have an enum with which I want to pick out a random value (for a basic card game).

Here is the code.

public enum CardSuit
	{
		Spades,
		Hearts,
		Diamonds,
		Clubs
	}

void Start ()
{
cardSuit = Random.Range((int)CardSuit.Spades, (int)CardSuit.Clubs,(int)CardSuit.Diamonds,(int)CardSuit.Hearts, + 1);
}

I pulled the (int) out of another code sample, but the error I get is "CS1501: No overload for method ‘Range’ takes ‘5’ arguments.

What argument am I missing then?

[Random.Range][1] takes only two arguments i.e. min and max value which is the range in which any random number will be generated. [1]: http://docs.unity3d.com/ScriptReference/Random.Range.html

4 Answers

4

As @HarshadK said, Random.Range arguments are min and max.

Because you didn’t explicitly set the integral type of the enum, it defaults to int. If you don’t explicity set the values of the enums, the first element in the sequence is 0 and +1 for each going down.

You can do(assuming the variable cardSuit is of type CardSuit(the enum):

public enum CardSuit
{
    Spades,
    Hearts,
    Diamonds,
    Clubs
}

void Start ()
{
    cardSuit = (CardSuit)Random.Range(0, 3);
    // or
    // cardSuit = (CardSuit)Enum.ToObject(typeof(CardSuit) , Random.Range(0, 3));
}

One more example that once again only applies to enums that haven’t had their default values set. We know we start at 0, but perhaps we don’t want to explicity set the max, you may end up updating the enum with more elements and that would require additional maintenance. Lets remove that extra step. System.Linq is required as a using.

// Snip
void Start ()
{
    cardSuit = (CardSuit)Random.Range(0, Enum.GetValues(typeof(CardSuit)).Cast<CardSuit>().Max());
}

values.Length-1 ;)

@thef1chesser it has to be values.Length since Random.Range never returns max value as the random number, so value.Length - 1 will never yield the last value.

I had to cast Enum.GetValues to (int) to get it to work in Range(int, int)

public enum Enemy{Scorpion,Orc,Human}
public Enemy enemy;

	void Awake(){
   enemy= (Enemy)Random.Range(0, System.Enum.GetValues(typeof(Enemy)).Length);
	}

Use this utility method in some Utility static class:

public static T RandomEnumValue<T>()
{
    var values = Enum.GetValues(typeof(T));
    int random = UnityEngine.Random.Range(0, values.Length);
    return (T)values.GetValue(random);
}

Then, use it in your game class like this:

private enum MyEnum
{
    One,
    Two,
    Three
}

private void Method()
{
    MyEnum e = Utility.RandomEnumValue<MyEnum>();
}

I think you should subtract 1 from your array length when generating random value, otherwise you may end up with IndexOutOfRangeException

This is great, thankyou

This is how you can choose a random number from enum using c# in Unity

enum EnumType
{
	one, two, three, four, five, six
}
EnumType varName;

void FunctionName()
{
	varName = (EnumType)Random.Range(0, 6);
}

What's the point of writing a less detailed answer which suggests the exact same thing that the accepted answer has already suggested 8 years ago?