BD Editors to support enums with the [System.Flags] attribute properly for things that aren't LayerMask

Xanto Nemot

New member
Hi Justin!

I don't know if this is strictly BD's domain or not, and I know it's potentially a niche use-case, but I figured I'd run it through you and see if you can tell me if this is something I can do myself or if it'd be a thing that could be added at some point.

Here's the deal. I'm using some enums with the attribute [System.Flags] on it, for example:

C#:
[System.Serializable]
[System.Flags]
public enum InteractionType
{
    None = 0,
    All = ~0,
    CanForceGrab = (1 << 0),
    CanForceMove = (1 << 1),
    CanForceThrow = (1 << 2),
    IsForceGrabbing = (1 << 3),
    IsForceMoving = (1 << 4),
    IsForceThrowing = (1 << 5),
    IsColliding = (1 << 6)
}


When I expose those as public vars on normal Monobehaviors, this is how the Inspector presents them:


Meaning, I can select more than one at the same time, so I can use the single enum for flagging.

Now, I'd like to use that flag enum as well inside a Behavior, as a Shared variable, and so I added this class:


C#:
using BehaviorDesigner.Runtime;

[System.Serializable]
public class SharedInteractionType : SharedVariable<InteractionType>
{
    public static implicit operator SharedInteractionType(InteractionType value) { return new SharedInteractionType { Value = value }; }
}

It works, the variable gets exposed and the code admits the use of it as an enum flag. However, inside any BD component, it only allows me to select one option at a time, which defeats the purpose of using enum flags:



Furthermore, I've seen that you have successfully been able to implement the behavior I need with the SharedLayerMask class, so I wonder what I'm doing differently, and if I could achieve this the same way you did.

Thank you beforehand,

Xanto
 
Last edited:
I didn't know about the Flags attribute - good to know! This should be something that you can add using object dawers:


You'll want to add the attribute version. You can use a MaskField to select multiple objects.
 
Thank you very much for the pointer Justin!

Unfortunately I've tried a lot and I've only managed to do it if I create a wrapper class, and not for the enums directly. I notice the System.Flags is a special kind of attribute, in that it's meant for classes, and not for fields. It's not the best that I have to wrap it in a class, when I only need the enum, but I'll get by unless you have an idea of what I'm doing wrong.

I'll share what I've done below to at least make it work for fields inside BD Editors (with a wrapper class), so others can use it if they want to:

Original attribute (for reference):

Code:
using System.Runtime.InteropServices;

namespace System
{
    [AttributeUsage(AttributeTargets.Enum, Inherited = false)]
    [ComVisible(true)]
    public class FlagsAttribute : Attribute
    {
        public FlagsAttribute();
    }
}

ObjectDrawerAttribute:


Code:
using BehaviorDesigner.Runtime.Tasks;
using System;

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class FlagsAttribute : ObjectDrawerAttribute
{
    public FlagsAttribute() { }
}

FlagsDrawer:

Code:
using UnityEngine;
using UnityEditor;
using BehaviorDesigner.Editor;
using BehaviorDesigner.Runtime.ObjectDrawers;

[CustomObjectDrawer(typeof(FlagsAttribute))]
public class FlagsDrawer : ObjectDrawer
{
    public override void OnGUI(GUIContent label)
    {
        var flagsAttribute = (FlagsAttribute)attribute;

        value = EditorGUILayout.EnumFlagsField(label, (System.Enum)value);
    }
}

SharedCustomClass:

Code:
using BehaviorDesigner.Runtime;

[System.Serializable]
public class CustomClass
{
    [Flags]
    public InteractionType interactionType;
}

[System.Serializable]
public class SharedCustomClass : SharedVariable<CustomClass>
{
    public static implicit operator SharedCustomClass(CustomClass value) { return new SharedCustomClass { Value = value }; }
}
 
Top