TylerTemp / SaintsField

A Unity Inspector extension tool focusing on script fields inspector enhancement
MIT License
148 stars 9 forks source link

Support `Enum` for `Show/Hide/Enable/Disable`-`If` #11

Closed ACCIAI0 closed 4 months ago

ACCIAI0 commented 4 months ago

In particular, i'd like to know if they can also check for methods and properties in addition to fields. another thing that would really great is if they could check for specific values of enum fields and if they could be also logically chained in an "and" statement. Too bad they can't do that yet, because it look like a very powerful alternative to Odin!

TylerTemp commented 4 months ago

Hi,

Methods/Properties

if they can also check for methods and properties

For the decorator itself, The parameters can be methods or properties or fields.

[DisableIf(nameof(IsDisabledByMethod))] public string methodChecker;

public bool IsDisabledByMethod()
{
    // add your logic here
    return true;
}

// change your getter accordingly. This is just an example
public bool IsDisabledByProperty
{
    get => true;
    private set {}
}

[DisableIf(nameof(IsDisabledByProperty))] public string propertyChecker;

image

As for the decorated target, using on method is possible with SaintsEditor enabled. Because of the limitation from Unity, this feature requires an Editor level component.

To enable it (read more about it here):

Window - Saints - Apply SaintsEditor. After the project finish re-compile, go Window - Saints - SaintsEditor to tweak configs.

Once it's done, you can use PlayaShowIf/PlayaHideIf/PlayaEnableIf/PlayaDisableIf, which are an "upgraded" version of ShowIf/HideIf etc. They works for both methods and normal fields.

public bool showMyMethod;

#region  example of using property value
[Button, PlayaShowIf(nameof(showMyMethod))]
public void MyMethod1()
{
    Debug.Log("Method1");
}
#endregion

#region example of using method callback
#if UNITY_EDITOR  // this macro is not required, but in case you want to call some editor only methods
public bool ShouldShowMyMethod()
{
    // write your logic here
    return showMyMethod;
}
#endif

#if UNITY_EDITOR
[Button, PlayaShowIf(nameof(ShouldShowMyMethod))]
#endif
public void MyMethod2()
{
    Debug.Log("Method2");
}
#endregion

// this works on normal field too
[PlayaShowIf(nameof(showMyMethod))]
public int myInt;

It works just like ShowIf:

image

image

Please note, that once you enable SaintsEditor globally, meta attributes from NaugutyAttributes will no longer work. If you using Odin, you need to disable Odin's inspector.

Properties as Target

and properties in addition to fields.

If you mean the properties as target (well, as parameters, see section above)

SerializedField for properties works fine with either ShowIf/HideIf and PlayaShowIf/PlayaHideIf.

Non-SerializedField for properties needs using PlayaShowIf/PlayaHideIf

public bool boolValue;

// DisableIf works on serialized property as expected
[field: SerializeField, DisableIf(nameof(boolValue))]
public Color ColorAutoProperty { get; private set; }

// non serialized property needs `Playa` to help
[ShowInInspector, PlayaShowIf(nameof(boolValue))]
public static Color MyStaticProp => Color.green;  // native Property

[ShowInInspector, PlayaShowIf(nameof(boolValue))]
public static Color StaticField = Color.blue;  // non serialized Property

[ShowInInspector, PlayaShowIf(nameof(boolValue))]
public static readonly string StaticReadOnlyField = "Building Nothing Out of Something";  // non serialized Field

[ShowInInspector, PlayaShowIf(nameof(boolValue))]
public const float MyConst = 3.14f;  // non serialized Field

image

image

(This feature has a bug in UI Toolkit I'm working on, please try this code AFTER the next release)

Enum Supports

if they could check for specific values of enum fields

Well, at this point enum is not supported yet. I'm not aware that this feature is so commonly needed. As both NaughtyAttributes and Odin support it, I'll consider adding this feature too.

A workround before it's added:

[Serializable]
public enum EnumState
{
    Off,
    On,
}

public EnumState state;

#if UNITY_EDITOR
[EnableIf(nameof(isOn))]
#endif
public string editable;

#if UNITY_EDITOR
private bool isOn() => state == EnumState.On;
#endif

Logic Operation

if they could be also logically chained in an "and" statement

Both Show/Hide/Enable/Disable-If and Playa version supports and & or operation, but it's not very readable.

I didn't add an and/or operation, but it's possible using this way:

For "Show" and "Disable", parameters are "and"

For "Hide" and "Enable", parameters are "or"

and multiple decorators are always "or".

public bool bool1;
public bool bool2;

// disable==1&&2
[DisableIf(nameof(bool1), nameof(bool2))]
public string disable1And2;
// disable==1||2
[DisableIf(nameof(bool1)), DisableIf(nameof(bool2))]
public string disable1Or2;

// enable==1&&2, which means disable==!(1&&2)==!1||!2
[EnableIf(nameof(bool1)), EnableIf(nameof(bool2))]
public string enable1And2;
// enable==1||2, which means disable==!(1||2)==!1&&!2
[EnableIf(nameof(bool1), nameof(bool2))]
public string enable1Or2;

image

This is not a readable API design, but it keeps the code clean and works (. It will stay as this unless there is a better way to do it.

TylerTemp commented 4 months ago

Enhancement

Support Enum for Show/Hide/Enable/Disable-If

ACCIAI0 commented 4 months ago

Thank you very much, you're awesome! Let me know when there's a working version of this

Also a thing if I may: whenever tagged by a saintsfield attribute fields get disaligned in the inspector, could you please add to their classlist BaseField<object>.alignedFieldUssClassName?

EDIT: Nevermind, I found the "disable label fix" menu. It doesn't fix all labels though

TylerTemp commented 4 months ago

Thank you very much, you're awesome! Let me know when there's a working version of this

Also a thing if I may: whenever tagged by a saintsfield attribute fields get disaligned in the inspector, could you please add to their classlist BaseField<object>.alignedFieldUssClassName?

EDIT: Nevermind, I found the "disable label fix" menu. It doesn't fix all labels though

This is because UI Toolkit itself is not aligned: All UI Toolkit Elements uses min-width label, EXCEPT PropertyField.

This bug has already been reported to Unity but never got fixed (yet)

There are several way to make it a bit better:

  1. Enable SaintsEditor. It'll make all label behavior as min-width label
  2. Add [UIToolkit] decorator to all other fields that does not have a SaintsField decorator.
  3. Completely disable UI Toolkit and stick with IMGUI (
TylerTemp commented 4 months ago

aligned

Hi, @ACCIAI0

I was not aware this "unity-base-field__aligned". Now all UI Toolkit has this class and the aligned looks good now.

Please upgrade to 3.0.0. to have a try.

TylerTemp commented 4 months ago

@ACCIAI0

This feature has been added in 3.0.3

Here is a quick example:

using SaintsField;

[Serializable]
public enum EnumToggle
{
    Off,
    On,
}
public EnumToggle enum1;
[ReadOnly(nameof(enum1), EnumToggle.On)] public string enumReadOnly;

Check the document for more advanced usage and limitations.

Please consider closing this issue if it's fixed. (And the issue will be closed if no activity for one week).

If the function itself has bugs, please open a new one rather than comment on this issue.

If you have more thoughts about this feature, please either comment here or open a new issue.

Cheers!

ACCIAI0 commented 4 months ago

@TylerTemp Hi! You're great thanks, I've tested it for a bit now and it seems to be working perfectly