Beginners question about enumerations

Hi there,

I have a beginner’s question regarding enumerations.

I have the following code written in a Player.cs script that is attached to a quad game object:

public class Player : MonoBehaviour
{
    public enum WeaponType
    {
        Gun,
        Knife,
        Axe
       
    }


    public WeaponType currentWeaponType;


    // Start is called before the first frame update
    void Start()
    {
       

    }

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

    }
}

I’m trying to understand why I only see the three constants of my enum(Gun,Knife,Axe) in the inspector when I make a variable of the enum’s type(currentWeaponType)?

If I was to delete the line where I declare the “currentWeaponType”, the dropdown list of the constants will disappear from my inspector window. I’m wondering why this is? Why can’t I see them when I just create the enumeration on its own? Why do I have to make a variable of the enumeration?

Any help would be great.

When you declare an enum, you’re declaring a type (like a class). It’s a new flavor of “int”, basically. You’re saying, “here are some different kinds of weapons that can exist”. (Note that this is different from the meaning of the word “type” as you’re using in your enum’s name which may make this discussion a little confusing)

Line 13 actually creates an instance of that type. You’re saying, "The CURRENT weapon is one of these kinds of weapons, and currentWeaponType is where that information is actually held.

If you were to, say, add a bayonet, you might want to have two types available on that weapon, so you might do this:

public WeaponType primaryWeaponType;
public WeaponType secondaryWeaponType;

Or better yet an array:

public WeaponType[] weaponTypes;

You want all of these to be defined by the same 3 choices, but their values are all independent of each other. So you need a type (your enum) and instances.

1 Like

Another way to see it is when you define the enum it could contain thousands of different values. Which one is it that your character yields? Thus you declare a variable of that type which stores the concrete value you out of the many you want. So the enum definition cotains all the possible values and the variable declaration one of the values. You have defined that enum inside your class so other classes have to reference your class to get to the enum.

Edit: And you want to give different players different weapons/items. Thus every one of them needs its own variable to store which weapon he/she wields.

1 Like

You mentioned that that when I declare an enum I’m sort of creating a class. You say that it’s like a different version of “int”? Does that mean that the four options I have in my enum are integers?

As in they’re valued 0,1,2? As in

Gun = 0
Knife = 1
Axe = 2

I didn’t realize you could declare two instances of the enum WeaponType class. This could prove to be useful!

Apologies, I’m struggling to understand how I could use an array to declare an instance of the WeaponType enum class?
I’ve tried to write “public WeaponType[ ] weaponTypes;” in my code but it just gives me an input box labelled “size” in my inspector? I’m not sure what you meant for me to do?

1 Like

Thanks, I have a better understanding now.
It seems that Unity will only show the options within the enumeration in the inspector when I’ve made an instance of that particular enumeration?
Or in your words it only shows in the inspector when I’ve declared a variable/instance that can be allowed to hold a concrete value that was taken from the enumeration?

Also - am I right in saying that enumerations can be called “classes” or “types”?

To further add to the great explanations above, as already mentioned when you declare an enum you actually declare a type. In the case of the OP the new enum type is a nested type since it was declared inside the Player class. However you can declare this type outside the Player class as well, which you would usually do when you want to use this type from more than one class. Of course since your enum type is public, you can use even the nested type from everywhere, but you have to refer to Player.WeaponType when you want to use it from outside the Player class.

So this is also possible:

public enum WeaponType
{
    Gun,
    Knife,
    Axe
}

public class Player : MonoBehaviour
{
    public WeaponType currentWeaponType;

Next thing is as it has been mentioned, an enum is essentially just an seperate strongly typed version of another integer type. By default, if not stated otherwise, it’s the type “int”. Each of the enum’s member is just a named constant. By default consecutive members just get the next numerical value based on the value of their predecessor.

Imagine this enum:

public enum MyEnum : byte
{
    A = 5,
    B,
    C,
    D = 2
}

In this case MyEnum is not an Int32 but just a byte value. A obviously has a value of 5. B has a value of 6 and C has a value of 7 while D has a value of 2. They are really just named constants.

As mentioned an enum type is essentially just a strongly typed alias for the underlying type, in this case a byte. A variable of our enum type can take any byte value, even those who do not have a named constant. So we can do this:

MyEnum enumVar;
enumVar = (MyEnum)42;

This code does work and the enumVar will actually contain the value 42. When you assign one of the constants, the variable does not hold the name of that constant but just the value of that named constant.

MyEnum enumVar;
enumVar = MyEnum.A;

This stores the number 5 in our variable. Of course enums are usually meant to specifically restrict the numbers one can assign and to give those otherwise magic numbers a meaningful name. Since an enum is a new seperate type, it also avoids accidental misuse as you would need an explicit cast if you want to assign something that has a different type. So technically a variable of an enum type is just a variable of type int, byte, long, … (whatever the underlying type of the enum is). However it acts as a seperate type on the high level language side to avoid accidental misuse.

Yep, exactly like that. In almost every way enums are integers - your CPU certainly treats them that way - they’re just a friendlier way to code them and read that code.

“Size” is how many elements are in the array. Put in something bigger than 0 in the “size” field, and you’ll see that many dropdowns for your list of enums. (I recommend finding a tutorial on arrays, they are insanely useful)

Enums aren’t classes, but they’re along the same lines as a class, yes. Enums and classes are both “types”.

1 Like

Try declaring, on a new line maybe, public WeaponType w1, w2, w3;. You’ll have 3 more Axe/Gun/Knife dropdowns, 1 for each.

If you don’t declare any variables, Weapons can still be axe/gun/knife but there’s no reason for Unity to display that. Only variables get Inspector slots.

Then a note: if enumerators seem like one more thing to confuse you, don’t use them. They’re exactly the same as this:

public int currentWeaponType=1;
// 0=gun, 1=knife, 2=axe

// somewhere down below:
  if(currentWeaponType==1) damage =4;
  else if(currentWeaponType==2) damage=6;

The only reason to use enums is it you keep forgetting which number is which weapon. An enum lets you type if(currentWeaponType=Weapons.Knife).

1 Like

Right. The enum definition holds all values you feed into it. You need a variable to hold a certain value.

If you have issues understanding that “basic” concept there is a great free ebook on C#.
Or you look after some tutorials:
https://www.w3schools.com/cs/cs_enums.asp

1 Like

So enumerations and classes are both types.

I know that classes hold variables and functions/methods that are kind of related to each other. And I now know that enumerations are basically a collection of constants. I can’t seem to find anything online related to “types” though.

Because both classes and enumerations are used to store related things together could types be described as a thing that organizes information?

Thanks for those links.

I think I understand it now. I just didn’t know the basic concept that only variables are displayed in the inspector and that’s the reason why I couldn’t see the drop down menu for the weapons when I didn’t create an instance of the WeaponType enumeration. But I get it now I believe. I just need to practice creating a few project with enums over the next week or so.

This is pretty basic stuff. I’d recommend a chapter in a real book about how variables work (the on-line 1-page stuff seems pretty bad, to me). But consider this:

public int n1, n2
public string str, w;
public Vector3 v3;
public Vector3 a;
public Color c1;

n1 and n2 can only be whole numbers, since they have type int. str and w can be letters, since the type is string. Vector3 was added by Unity (sort of how you added WeaponType). v3 and a get xyz slots since they have type Vector3 (which happens to be a class). c1 has type Color, which the Inspector is super helpful with.

Hopefully you can see the pattern: each variable has to be of a certain type, which comes first when you create it.

I understand different variable datatypes. I know what int, bools, floats etc are.

I just didn’t understand why I could only see the constants housed within my enumeration in the inspector when I declared an instance of the enumeration. Then someone pointed out that it’s because the inspector will only displayed declared variables. It wont let you see the constants held within the enumeration if you have yet to declare an instance of the enumeration.

It was a bit silly of me but I just didn’t get that particular part! I understand now though.

You wrote that you didn’t understand “types”. That’s an example of them in use. Every variable needs to be a certain kind – whole number, word, xyz-values … . That’s what a type is. With public WeaponType currentWeaponType; hopefully it jumps out how it matches the pattern in public int n;. It’s creating a variable, with WeaponType, in front, as the type.

Sometimes you can take something you want to do and work backwards to the basics. But it’s often easier to restart and work up from the basics.

2 Likes

I know this is a bit of a tangent to my original question but I’ve been trying to figure out a way of scrolling through the different weapons in my WeaponType enumeration with two of the buttons on my keyboard. In this case I would like to use the Q and E buttons to be able to go back and forth between the different weapons.

From looking online I’ve found this solution:

private var numberOfWeaponTypes = System.Enum.GetValues(WeaponType).Length;


if(Input.GetKeyDown(KeyCode.E)){
    weaponType += 1;
    if (weaponType == numberOfWeaponTypes) weaponType = 0;
}
else if(Input.GetKeyDown(KeyCode.Q)){
    weaponType -= 1;
    if (weaponType == -1) weaponType = numberOfWeaponTypes-1;
}

However when I write this code into my script I get the following error " error CS0825: The contextual keyword ‘var’ may only appear within a local variable declaration or in script code"

I read that you can get this error because C# needs you to specify what type the variable is sometime so I’ve tried changing numberOfWeaponTypes to an integer like so:

private var numberOfWeaponTypes = System.Enum.GetValues(WeaponType).Length;

However this returns a “CS0119” error and I’m having trouble understanding what this error actually means from reading about it online. I’m just wondering does anybody know what I’m doing wrong?

“var” can’t be used outside of a function. For a class-level variable (that is, a “field”) you have to use a specific data type rather than “var” - in this case, “int”.

For initialization, you generally can’t do any sort of logic when outside of a function (in-line initialization only works with constants) and .Length counts as logic, so you’ll have to set its value in Awake() or something like that.

I’ve written the following code but I seem to be getting a CS0119 error which means I’m missing a ‘}’ bracket even though I literally can’t find any mistake in the code at all? :

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

public class Player : MonoBehaviour
{

    public enum WeaponType
    {
        Gun,
        Sword,
        Dagger
    }


   
 
    void Awake()
    {
         private var numberOfWeaponTypes = System.Enum.GetValues(WeaponType).Length;
    }

  



}

I’ve tried both declaring “numberOfWeaponType” as an int and as a var within the awake function but I still get the CS0119 error for some reason.

You can’t have “private” inside a function. It’s saying missing } because the compiler is thinking the you clearly meant to end the Awake() function before doing this thing that can only be done in the root level of a class.

I’m not sure what I’m supposed to do with that line then. I’ve tried removing private and just declaring it as ‘int’ within the awake function but then I get the following error:

error CS0119: ‘Player.WeaponType’ is a type, which is not valid in the given context

You’re getting closer. In certain situations (usually when you’re using the type itself as a variable/parameter/etc), you need to use typeof(SomeTypeName), otherwise the compiler has trouble working out the syntax.

public class Player : MonoBehaviour
{
public enum WeaponType
    {
        Gun,
        Sword,
        Dagger
    }


  
    private int numberOfWeaponTypes;
    void Awake()
    {
         numberOfWeaponTypes = System.Enum.GetValues(typeof(WeaponType)).Length;
    }
}