Troubles Creating a Enum for NativeHashMap<>

Hello developers, Im trying to create a NativeHashMap<MyEnum, Entity> to recreate my Mono Dictionary pointing to my BlobAssetReference. My idea here is to pass a enum though and get the blob asset entity. First off is this a good approach to this problem?

Secondly I cant seem to get my enum into the HashMap. Im getting the error:
The type ‘Types.Buildings’ must be convertible to ‘System.IEquatable<Types.Buildings>’ in order to use it as parameter ‘TKey’ in the generic struct ‘Unity.Collections.NativeHashMap<TKey,TValue>’.

I have searched around and cant seem to get this to work with current postings about it. here is a snippet of the Types class.

public static class Types
{
    public enum Buildings: byte
    {
        Assembler,
        Miner,
        Forge,
        PowerGlobe,
        Refinery,
        Grinder,
        JumpPad,
        Splitter,
        Trough,
        Hub,
        None
    }
}

You can use NativeHashMap<int, Entity> and then convert your enum to int while accessing to hashmap. Also why you need enums? Why just not store collection of entities, if you doesn’t use enums in code, of course.

1 Like

Thank you for the response! I will try this approach.

The idea behind the enum is that when we add new Types of Buildings we can correctly identify them in code by their enum value, I’m afraid of placing Index’s in the scripts as they will become outdated overtime.

If you absolutely must use enums directly in your hashmap, and can’t change it to int, you might be able to do some trickery like this:

public struct U8Enum<T> : IEquatable<U8Enum<T>>
        where T : unmanaged, Enum
    {
        byte Value;

        public unsafe U8Enum(T value)
        {
#if UNITY_EDITOR
            UnityEngine.Assertions.Assert.AreEqual(sizeof(T), 1, "Underlying type of T is not byte");
#endif

            Value = (byte)UnsafeUtility.EnumToInt(value);
        }

        public static implicit operator T(U8Enum<T> value) => UnsafeUtility.As<byte, T>(ref value.Value);
        public static implicit operator U8Enum<T>(T value) => new U8Enum<T>(value);
        public static implicit operator byte(U8Enum<T> value) => value.Value;

        public bool Equals(U8Enum<T> other) => UnsafeUtility.EnumEquals(this.Value, other.Value);
        public override int GetHashCode() => Value.GetHashCode();
    }

With that you should be able to use enums in your hashmaps like so:

        var a = new NativeHashMap<U8Enum<Buildings>, int>(1, Allocator.Persistent);
        a[Buildings.Assembler] = 2;
        a.Dispose();

One option you could also do is to not use a hashmap, but an array instead then index into it by converting the
enum to an int.

Though as Tony said, if you have other options for structuring your code that might be better.

1 Like

Thank you Per-Morten, I just tested (int)enumValue and it worked like a charm. Now to test if I can get this HashMap into a ForEach so I can reference the blobs in parallel.