Can enums be kept in monobehaviour scripts without them being instanced?

I’ve always kept all my enums in a separate Enums.cs because, in my mind, they were essentially static and I didn’t want to be instancing the enum type into every Monobehaviour using that script. I’ve realized recently that I was thinking about enums wrong, since they’re a type, and thus there is no concept of “static” (hence why you can’t mark an enum as static). But I’m still unable to quite clear this up: can I safely declare an enum type in a Monobehaviour script that is instanced on multiple gameObjects without it needing to instance a new enum type for each one? Is it effectively like a static member?

I’d much prefer to keep my enums in the script where they’re relevant, but I want to make sure I’m not adding overhead to each instance of that script.

Yes you absolutely can put the enums in the same script. I always keep enums in the same .cs file as the class that uses them the most. Really Enums aren’t even so much types like class or struct are as they are just named integers (or bytes or shorts or whatever).

When you have Stuff.cs that contains public class Stuff : Monobehaviour, adding Stuff.cs to an object is only adding Stuff : Monobehaviour to it. You can have anything else you want in Stuff.cs and it wont matter because only the monobehaviour gets added as a component.

Monobehaviour actually inherits from Behaviour, which itself inherits from Component, and a GameObject really has several Components. Anything that doesn’t derive from Component can’t be added to a GameObject. Enums can’t inherit so no worries.

When you drag a .cs file onto a GameObject, Unity will look to see if that file has a class with the same name that inherits from Monobehaviour, and if so, will add it. You don’t add .cs files to GameObjects, only the Monobehaviour they define. It’s entirely possible to have a .cs file with no monobehaviours, or one with more than just a single type. The only caveat is the Monobehaviour if you have one should be of the same name as the file.

A Note on Enums

An Enum is just an int. (Ok, not really, you can tell it to be other integer types, like byte, short, ushort, long, etc… It can’t be a float or anything else). But it’s an int by default. Thus, you can treat your enums like integers, because that’s all they are. In fact, it’s entirely possible to say

int i = (int)MyEnum.SomeValue;


int i=2;
MyEnum m = (MyEnum)i;

(Assuming your enum really is an int. If it’s a different type, use that type.).

This even works for int values that aren’t defined in your enum. This is, in fact, the basis for bitflags. The enum only has names for 1 and 2, but a value of 3 means ‘both 1 and 2’ without needing a special name for every combination.

Now, if your monobehaviour has a field of an enum type, you have that enum in memory for that instance anyway, no matter where the enum is defined. Enums aren’t static, nor are they really objects. They’re just values.

Long story short:
Enums are just integer types. Nothing static about them, nothing instanced about them. And what .cs file it goes in doesn’t really matter. If it’s defined somewhere, you can use it. Don’t quote me on this, but I think most compilers just turn them into integer constants at compile time anyway, so they’re only there to make your code more readable (Or for dropdowns in Unity).