简体   繁体   中英

C#/Unity - How to make mixed/multiple select menu in Scriptable Object with enum

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 ?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM