Search Unity

How to make a Type dropdown for a base type using popupField<T>?

Discussion in 'UI Toolkit' started by Sangemdoko, Jan 11, 2020.

  1. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    222
    Hi, I've been trying to make a custom field for a Type dropdown for hours now and I can't get any of the popup/dropdown classes to work the way I want.

    The purpose is to allow someone to choose a Type that derives from a base class/interface and then I can use that as a key to a dictionary of prefabs. I have a script that will check what prefab to spawn depending on the type passed as parameter. Usually, that type will be the type of a component on the root of the prefab.
    The reason I need that dictionary is a bit complicated to explain because it is very particular to my current project. But I need the type somewhere else so that I can get values from override properties through reflection to customize some unity internal editor stuff.

    PopupField<T> does not have a function that lets me change the choice list. Choices is internal...
    DropDownMenu is not a VisualElement so I'm not sure how I'm supposed to display it.

    I tried other things but I am essentially stuck now. I plan to use a GenericMenu in the mean time, but I'd really like to find a way to make this work properly.

    Any help is greatly appreciated.
     
  2. larsolm5853

    larsolm5853

    Joined:
    Oct 24, 2017
    Posts:
    21
    Hey! We have an MIT licensed repo with a bunch of custom fields and drawer attributes that may be to your liking.
    Specifically, we have a TypePickerField which does exactly as you desire (set a base Type and show a list of all derived types). I attached a zip of the files from the repo that you will need. I haven't tested it so hopefully I included everything necessary. Let me know if you get some compiler errors and I'll make sure to get all the correct files.

    The only caveat is that the field stores the chose type as the AssemblyQualifiedName string (this is so it can be used in serialization or binding) so you will have to convert it manually but that should be pretty trivial. Basically, to do what you want you'll do something like the following:

    Code (CSharp):
    1.  
    2. var typePicker = new TypePicker("My Type", typeof(INSERT_BASE_TYPE))
    3. {
    4.     value = INSERT_DEFAULT_TYPE.AssemblyQualifiedName
    5. };
    6. typePicker.RegisterValueChangedEvent(evt =>
    7. {
    8.     var newType = Type.GetType(evt.newValue);
    9.     // Do what you need here.
    10. }
    11.  
    Let me know if you have any issues and if you want to check out the rest of the stuff in there here is a link to the repository:
    https://github.com/pirhosoft/PiRhoUtilities
     

    Attached Files:

  3. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    222
    Thank you, that's pretty neat.
    I might use a few things you offer in that repo.

    I actually managed to come up with a solution myself and it's very similar to yours, it also serializes the AssemblyQualifiedName.

    And for people that stumble on this thread. Turns out you need to pass the PopupField<T> choices in the constructor, they cannot be modified afterward.