I'm working on a game with Unity in which the player has some spells. I have an enum that contains all of these and I want to attach them a bool value. I think I can use a System.Collections.Generics.Dictionary
with the Spell
s as Key
s and the Boolean
as Value
, but is there a simpler way to do such a thing?

- 180,369
- 20
- 160
- 215
-
2Why is a dictionary not simple enough for you? Please provide at least some usage examples. – dymanoid Feb 28 '20 at 12:41
-
1if `enum` is a simple one (i.e. starts from `0`), e.g. `public enum MyEnum {Fireball, Levitate, ...}` you can try *array* : `bool[] hasSpells = ...` `if (hasSpells[(int)spell]) {...}` – Dmitry Bychenko Feb 28 '20 at 12:42
-
Not to offend or be rude, but I think Dictionaries are actually relatively simple data structures. You have a key and an associated value, that's basically it. If you're having trouble with Dictionaries, I'd recommend you start off by doing some "classical" programming exercises and challenges before you attempt writing a fully fledged game, even in such a feature rich game engine like Unity – MindSwipe Feb 28 '20 at 12:43
-
If your enum is a bitmask then you can use a single value to indicate all of the available enum values for the user. Some info here: https://stackoverflow.com/questions/3261451/using-a-bitmask-in-c-sharp – David Feb 28 '20 at 12:45
-
Yes, dictionnary are simple collections but it's not really what I expect. I want something just to say "this value from the enum is true, this one is false". – Feb 28 '20 at 12:46
-
@AnoopRDesai what would happen when there are 10 enum values, 5 of which have been assigned to 0 and 5 assigned to 1? – ColinM Feb 28 '20 at 13:24
-
@ColinM Yes, my bad, I missed that somehow :) Will delete my comment. – Anoop R Desai Feb 28 '20 at 15:38
4 Answers
You can simplify Dictionary<Spell, bool> hasSpell
into HashSet<Spell>
(you want only Key
, not Value
from the initial Dictionary):
public enum Spell {
Fireball,
Levitate,
Resurrect,
};
...
HashSet<Spell> abilities = new HashSet<Spell>() {
Spell.Fireball,
Fireball.Levitate,
};
...
// If the hero can resurrect...
if (abilities.Contains(Spell.Resurrect)) {
// ...let him raises from the dead
}

- 180,369
- 20
- 160
- 215
-
This is not exactly what I wanted, but well, it works. It's so simple I didn't think about it. – Feb 28 '20 at 13:09
Individually the simplest way of pairing two data values is to use a value tuple. This feature can be used on any Unity version from 2018.3 onwards as that's when it stopped using outdated C# versions.
var spell = ("Fireball", true);
If you'd rather be more explicit about types:
(string, bool) spell = ("Fireball", true);

- 31
- 2
(This is another approach in making things "easy")
Yes, dictionnary are simple collections but it's not really what I expect. I want something just to say "this value from the enum is true, this one is false"
This sounds you need a nice class that encapsulates the less-simple or more low-level structure (e.g. dictionary or hashset). This will things easy from the outside / API-isde.
For example:
public enum Spell
{
Firebolt,
Rage,
Flash,
};
public class SpellState
{
private HashSet<Spell> _enabled = new HashSet<Spell>();
public void EnableSpell(Spell spell)
{
_enabled.Add(spell);
}
public void DisableSpell(Spell spell)
{
_enabled.Remove(spell);
}
public bool IsSpellEnabled(Spell spell)
{
return _enabled.Contains(spell);
}
}
Usage
var spellState = new SpellState();
spellState.EnableSpell(Spell.Rage);
// later
if (spellState.IsSpellEnabled(Spell.Flash))
{
spellState.DisableSpell(Spell.Rage);
// todo
}

- 33,915
- 22
- 119
- 174
You could use a single bitwise value by defining enum flags, so long as you have a limited number of spells.
[Flags]
public enum Spell : long
{
Firebolt = (1 << 0),
Rage = (1 << 1),
Flash = (1 << 2),
};

- 9,515
- 25
- 29