0

Here is my scriptable object:

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

[CreateAssetMenu(fileName = "New Armory Item", menuName = "Model Manager/New Armory Item")]
[Serializable]
public class ArmoryItemSO : ScriptableObject
{
    public int id;
    public GameObject mesh;
    public RaceBodySlot hidesBodySlot;
    public Textures textures;
}

public enum RaceBodySlot
{
    None,
    Head,
    Torso,
    Arms,
    Hands,
    Thighs,
    Legs,
    Feet,
    Tail,
    MainHand,
    OffHand
}

In the editor I have select menu for hidesBodySlot. However in that select menu I can choose only one option. How can I make it so I can choose more than one?

After that how can I get all the chosen options for hidesBodySlot ?

1 Answer 1

5

using the flags attribute on your enum

[Flags]
public enum RaceBodySlot
{
    None = 0,   // or define values via bit shifts:
    Head = 1,   // 1 << 0
    Torso = 2,  // 1 << 1
    Arms = 4,   // 1 << 2
    Hands = 8,  // 1 << 3

    ....

with [Flags] Unity will also automatically add the "Everything" option

with [Flags] Unity will also add a "Nothing" option (being 0) to it, if you've no option which is 0 in your enum.

This solutions uses bit-wise comparisons of single bits. So 0 will always mean "nothing" (as no bits are set).

  • In this example Head would've the binary represantion of: 0001
  • In this example Torso would've the binary represantion of: 0010
  • In this example Arms would've the binary represantion of: 0100
  • ...

That's why it is important to use multiples of two.

To check whether such an individual bit is set or create some combinations via code, see below:

public static class RaceBodySlotExtensions
{
    RaceBodySlot AddSlot(this RaceBodySlot self, RaceBodySlot other)
    {
        return self | other;
    }

    RaceBodySlot RemoveSlot(this RaceBodySlot self, RaceBodySlot other) 
    {
        return self & ~flag;
    }
        
    public static bool HasFlag(this RaceBodySlot self, RaceBodySlot flag){
        return (self & flag) == flag;
    }

}

with this extensions method (also see extension class) you can use them in code like

myItem.hidesBodySlot.HasFlag(RaceBodySlot.Head)

or

myItem.hidesBodySlot = (RaceBodySlot.Head).AddSlot(RaceBodySlot.Torso)
Sign up to request clarification or add additional context in comments.

3 Comments

The option None is not required ;) The Inspector drawer for flags automatically adds the two options None and Everything ;) Afaik you just have to make sure to start the flag values at 1
@derHugo that is what I wrote, that unity will automatically add "Nothing" (if no 0 value is in the enum) and "Everything".
Ok let me rephrase that: You definitely shouldn't define it yourself ;) This is a little bit misleading because someone might think it is just another option for a flag (the same way a normal enum simpy starts with 0 by default) ... but 0 has a predefined meaning for a flag .. it always means None. I just wanted to emphasize this to someone (like OP) who doesn't know flags yet ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.