Enum cast to int gives wrong result

So, when i cast GroupName to int, for example like this: GroupID = (int)(GroupName.Ship) i have correct result (2). But! … when i call GroupNameChanged from inspector i get GroupID equal to 3 instead of 2. I debugged this function and (int)Group (when group is Ship assigned from inspector) really returns 3 instead of 2. Why is that? What i’m doing wrong?

I think 3 is 2 plus 1. Because when i uncheck everyting in inspector, it set 1 instead of 0. And 9 for Port, instead of 8. This is just crazy…


image

[System.Flags]
    public enum GroupName : int
    {
        //Default = 0,
        Ship = 1 << 1,
        Fighter = 1 << 2,
        Port = 1 << 3,
    };

public int GroupID;

    [OnValueChanged("GroupNameChanged")]
    public GroupName Group;

    private void GroupNameChanged()
    {
        GroupID = ((int)Group);
    }

Enums enums are bad in Unity3D if you intend them to be serialized:

It is much better to use ScriptableObjects for many enumerative uses. You can even define additional associated data with each one of them, and drag them into other parts of your game (scenes, prefabs, other ScriptableObjects) however you like. References remain rock solid even if you rename them, reorder them, reorganize them, etc. They are always connected via the meta file GUID.

Collections / groups of ScriptableObjects can also be loaded en-masse with calls such as Resources.LoadAll<T>();

Best of all, Unity already gives you a built-in filterable picker when you click on the little target dot to the right side of a field of any given type… bonus!

Do you understand what the bitwise shift operators do? You’re moving the actual bits (the 1s and 0s), of the integer value across 2 digits. So 1 (0001) bit shifted left by 2 is 4 (0100).

If you want to use bitwise flags, just make each of the values powers of 2. Ergo 1, 2, 4, 16, etc.

But also what Kurt said. Enums are fragile and avoid them as much as possible.

2 Likes

AFAIK Unity now more or less supports enums that are marked with “System.Flags” and should show them as a bit mask. However I think it does have some limitations. Is there a reason why you skipped the least significant bit? You start your enum with value 2 (1<<1) instead of 1 (1<<0). Try to not have any gaps in your bitmask. Apart from that, we don’t know if you may use a custom PropertyDrawer or Editor and what else may influence your “Group” variable.

2 Likes