Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Request for a Better Solution for Conditionally Showing Fields in the Inspector

Discussion in 'Scripting' started by QuinnCG, Mar 5, 2022.

?

Do You Want This Feature?

  1. A Lot

  2. A little

  3. Not Really

  4. No

Results are only viewable after voting.
  1. QuinnCG

    QuinnCG

    Joined:
    Jan 30, 2020
    Posts:
    6
    Unity feature requests have been removed and I'm not sure if this is the correct form for something of this nature. If there is a better solution already in Unity, please tell me; I've been digging through forums and documentation and can't find it.

    Having to create an editor window is a hassle. There should be a way to dynamically show or hide fields in the inspector based on the value of bool or possibly even on an expression so you could invert a bool condition or check if an enum is set to a certain state.
    I'm not sure if this is possible to implement via an attribute.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,713
    Is it? Maybe the first time, but after that you just sorta hammer it out after copy/cloning it and it's done. That also lets you nail down exactly the behaviour you want.

    Go look at Odin Inspector and / or Advanced Inspector for ready-made solutions.
     
  3. QuinnCG

    QuinnCG

    Joined:
    Jan 30, 2020
    Posts:
    6
    Interesting take, but I still don't think it's that unreasonable of a request. I was kind of surprised when I found out it wasn't already a thing.
    If I have an enemy component that has an enum for whether it's a melee fighter or a ranged one and I want the properties for melee trace range to only be visible when it melee and the properties for projectile speed to only be visible range, then it is a hassle to have to create an editor window. The hassle increases when I have more (very separate) things that each require this feature (not an entire editor window).
    If I make an Item scriptable object and I want to have booleans that enable the functionality of the item like is edible and have properties about what happens when you eat it only show in that case; there could also be booleans on whether an item is a melee item, whether its a piece of armor, etc.
    I agree the editor window is a very good tool when you need it, but it's overkill for doing what I've been talking about and I shouldn't be expected to drop $50+ on a store asset that is still overkill for such a seemingly basic feature. I'd really like to see it make its way into the engine in a future update.
     
  4. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,001
    After almost a decade I still dislike / avoid making editor windows if I am able to.
     
    Dextozz and daneobyrd like this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,713
    After almost a decade of making editor windows I rip them out faster than the class itself... and when I do, I almost always copy/paste from another project to start with, then rip-tear-shred until it does precisely what I want.

    Are you perhaps looking for a custom property drawer?? That lets you override parts of an editor window based on what the underlying type is.
     
    Bunny83 likes this.
  6. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,001
    And you manage that? Unless it's something super simple, I find the editor window API and surrounding styling options so unintuitive I can almost never get it to do something exactly how I want it. (or at least I stop before I get there because I can only write so much editor code before losing whatever sanity I have left).
     
    daneobyrd likes this.
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,713
    I stop once the barest needs are met... I'm no sadist.

    Just a couple of GUILayout.Label() lines explaining what is what and then some condition tests to reveal / hide areas of the GUI are usually plenty. I try to keep every individual object pretty simple.

    I also drop in HeaderAttributes in my normal scripts a lot to explain stuff... that practice has saved SO many hours of future work when you have well-documented inspector panels:

    Screen Shot 2022-03-05 at 1.57.47 PM.png
     
    AcidArrow likes this.
  8. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    326
  9. daneobyrd

    daneobyrd

    Joined:
    Mar 29, 2018
    Posts:
    101
    Writing anything for the inspector has been a pain point for me because there is so much required boilerplate code and most tutorials are hyper specific to whatever use-case.
     
    DragonCoder likes this.
  10. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,058
    UI Toolkit does make it a lot easier to create custom tools & inspectors. But it would be nice if you could create a uxml document that is the same as the default inspector for that class. It makes making changes easier from there.

    It would be nice to have an attribute with a predicate check whether it should show that field or not.
    If that is the only thing you require from that inspector then creating a custom inspector just to show / hide that field is a bit of work. Even if you have done it before and can copy paste. It is more work than a simple attribute.

    In some cases you can split it up in components. ProceduralUI from the asset store does this based on the enum value.
    They have a modifier type which is either: free, only one edge, round and uniform. Each modifier type is their own component. So the values tied to the modifier is only in their own component but not on the main component that uses it.

    They are busy with converting the inspector from IMGUI to UI Toolkit in Unity 2022.2? (not sure if this already happens in 2022.1)
    I noticed that the
    [Header]
    and
    [Space]
    attribute weren't working anymore. Because those attributes are based on IMGUI.
     
  11. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,713
    Aye, which is why I wrote this above:

    If you're not making a commercial product out of your actual editor code, then you're only impressing yourself by struggling past the basic economic benefit of getting some repetitive task (a little more) automated in the first place, or embedding some extra semantic structure in the data presentation.
     
  12. daneobyrd

    daneobyrd

    Joined:
    Mar 29, 2018
    Posts:
    101
    All the more why a built-in attribute from Unity would be nice.
     
  13. theblindhawk

    theblindhawk

    Joined:
    Apr 21, 2017
    Posts:
    4
    Yes, it is absolutely a hassle to create an editor script for something as small as conditionally showing and hiding an initializer parameter.
     
  14. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,862
    This is not as easy as some would like to believe. If you to do this via attributes, you have to work around the fact that you can only pass compile-time safe data-types through their constructor. You can't pass methods, or instance members, or anything that would make this intuitively possible.

    There's a reason why the Odin Inspector devs had to make a whole system to resolve strings as code to make this kind of feature possible. Because it's not really possible otherwise out of the box with the C# language in general. I don't fault Unity for not going this far for a feature like this. It's a huge task on it's own.

    If you want this kind of feature, just get Odin Inspector.
     
    Last edited: Sep 8, 2023
    Kurt-Dekker, Bunny83 and CodeRonnie like this.
  15. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,114
    I've found that for me 99% of situations just require simple functionality like
    [ShowIf(nameof(boolField), true)]
    . I once went through the trouble of implementing support for complex expressions that can contain nested parentheses and all that, only to basically never have any use for it :D A big YAGNI learning moment for me.

    It's pretty easy to create basic functionality like this, by creating a custom Editor for
    typeof(Object)
    that skips drawing fields with the attribute when the condition isn't true. Since you have access to the serialized properties of all members, it's easy to find the one with a matching name and to get it's value. You can just use ToString or JsonUtility for both the required value passed to the attribute as well as the value of the serialized property and check if the results are the same.

    Where it becomes more complicated is if you want this support deeper down inside nested properties, and not just for root properties of the serialized object.
     
    Bunny83 likes this.
  16. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,525
    Right, for such complex scenarios, there will always be a limit or situations that can't be handled by a system. Those requests to "hide certain fields when a certain condition is true" is way too specific and not at all a common problem. Go through your current project. Have a look at ALL your components and give me a percentage in how many of them you would use a feature like this.

    So it's a niche problem which doesn't have a simple solution that covers all potential cases. Because sooner or later someone wants to check a condition that refers to a field in a referenced scriptable object. Next someone wants to check a field of a singleton or a static variable. Next someone wants property support and essentially have the condition to be a callback function. This is a never-ending story. Like SisusCo said, such very simple conditional attributes and property drawers are out there, but are limited. If you need something more specific, you have to create that thing.
     
    SisusCo likes this.
  17. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    284
    Thinking about the motivating issue, different types of characters with different properties, and how I would handle showing different data in the inspector, I would probably just use scriptable objects. Rather than try to manually hide properties I would just create some kind of base class for characters and derive a player and enemy character from that, trying to keep the hierarchies as flat as possible. I doubt I would need to derive more classes. The properties contained in those specific characters or enemies could be some base class of scriptable object like Attack or Action, and then from there I would derive another relatively flat hierarchy with properties that suit the needs of that specific class. So, maybe something like MeleeAttack, RangedAbility, etc. Then I would create instances of those actions/attacks or equipment, appearance, etc. etc. which are referenced by the specific characters. You could do something similar with SerializeReference, but the trouble with SerializeReference serializing different classes is the editor support. You have to implement your own method of selecting which specific derived type you do want to serialize and display that type reference properly in the editor, but people have done it. Then everything displays only the data that it needs and can easily be swapped around in the editor without unnecessary conditionals or reflection.

    Edit: I would obviously not name a class Action, as .NET already uses that type name, but you get the gist.