Search Unity

Resolved Can I create a dropdown, with colors?

Discussion in 'UGUI & TextMesh Pro' started by Were_Elf, Apr 22, 2022.

  1. Were_Elf

    Were_Elf

    Joined:
    Feb 25, 2022
    Posts:
    53
    upload_2022-4-22_20-19-45.png
    I want something like this, but wouldn't mind if it's simpler... like having only 1 column, no gradient and no borders.
    The condition that I'd like to have fulfilled tho would be: for me to be able to set up the colors from a script, and not having to manually create a sprite for each color.
    If such thing is possible, what would be the way to implement it?
     
  2. Were_Elf

    Were_Elf

    Joined:
    Feb 25, 2022
    Posts:
    53
    I almost have a working version.... Just need to think of how to set the colors in the actual list...
    Code (CSharp):
    1. public class DropdownColors : MonoBehaviour
    2. {
    3.     [SerializeField] private Sprite sprite;
    4.     private Dropdown dropdown;
    5.     private Image myImage;
    6.  
    7.     void Start()
    8.     {
    9.         dropdown = GetComponent<Dropdown>();
    10.         foreach(Image img in GetComponentsInChildren<Image>())
    11.         {
    12.             if(img.gameObject!= gameObject)
    13.             {
    14.                 myImage = img;
    15.                 break;
    16.             }
    17.         }
    18.         dropdown.ClearOptions();
    19.         List<string> options = new List<string> {"","","","","","","","","","","","",""};
    20.         dropdown.AddOptions(options);
    21.         foreach(var option in dropdown.options)
    22.         {
    23.             option.image = sprite;
    24.         }
    25.     }
    26.  
    27.     public void ValueChanged()
    28.     {
    29.         myImage.color = (dropdown.value + 1).GetColor();
    30.     }
    31.  
    32. }
    Code (CSharp):
    1. public static class ColorExtensions
    2. {
    3.     public static Color GetColor(this int intColor)
    4.     {
    5.         if (intColor == 1) return new Color(0, 0.65f, 0, 1);
    6.         if (intColor == 2) return Color.red;
    7.         if (intColor == 3) return Color.blue;
    8.         if (intColor == 4) return new Color(0.5f, 0, 0.65f, 1);
    9.         if (intColor == 5) return new Color(0.5f, 0.33f, 0, 1);
    10.         if (intColor == 6) return Color.gray;
    11.         if (intColor == 7) return new Color(1, 0.5f, 0, 1);
    12.         if (intColor == 8) return Color.yellow;
    13.         if (intColor == 9) return Color.magenta;
    14.         if (intColor == 10) return Color.cyan;
    15.         if (intColor == 11) return new Color(0.7f, 1, 0, 1);
    16.         if (intColor == 12) return Color.black;
    17.         if (intColor == 13) return Color.white;
    18.         return Color.clear;
    19.     }
    20. }
     
  3. Were_Elf

    Were_Elf

    Joined:
    Feb 25, 2022
    Posts:
    53
    And I managed to solve it.... The way I did it seems to be sub-optimal, but it's at least working :)
    Code (CSharp):
    1. public class DropdownColors : MonoBehaviour
    2. {
    3.     [SerializeField] private Sprite sprite;
    4.     private Dropdown dropdown;
    5.     private Image myImage;
    6.  
    7.     void Start()
    8.     {
    9.         dropdown = GetComponent<Dropdown>();
    10.         foreach(Image img in GetComponentsInChildren<Image>())
    11.         {
    12.             if(img.gameObject!= gameObject)
    13.             {
    14.                 myImage = img;
    15.                 break;
    16.             }
    17.         }
    18.         dropdown.ClearOptions();
    19.         List<string> options = new List<string> {"","","","","","","","","","","","",""};
    20.         dropdown.AddOptions(options);
    21.         foreach(var option in dropdown.options)
    22.         {
    23.             option.image = sprite;
    24.         }
    25.         myImage.color = (dropdown.value + 1).GetColor();
    26.     }
    27.  
    28.     public void Shown()
    29.     {
    30.         int i = 1;
    31.         foreach(var img in transform.Find("Dropdown List").GetComponentsInChildren<Image>())
    32.         {
    33.             if (img.gameObject.name == "Item Image")
    34.             {
    35.                 img.color = i.GetColor();
    36.                 i++;
    37.             }
    38.         }
    39.     }
    40.  
    41.     public void ValueChanged()
    42.     {
    43.         myImage.color = (dropdown.value + 1).GetColor();
    44.     }
    45. }
     
  4. Matsyir

    Matsyir

    Joined:
    Mar 13, 2019
    Posts:
    29
    This post helped me a lot to do something similar, where I just wanted to have unique color backgrounds for a more "regular" dropdown. Thank you for posting your process!

    One thing though, with your code examples we don't see how Shown() is called. I'm not sure how you did it, and at first I was a little confused and had to do a bit more digging beyond this post. There are many ways to do this, and I was looking for some type of native event listener, but there doesn't seem to be anything like that. What I did is I added an "Event Trigger" script onto the dropdown, and assigned it an OnClick function similar to your Shown().

    upload_2022-9-1_12-11-15.png

    Code (CSharp):
    1. // when the node selection dropdown is opened, set the bg colors of each option to its
    2. // respective node color. This is called using EventTrigger::OnClick set on the dropdown.
    3. public void OnNodeSelectionDropdownOpened()
    4. {
    5.     Image[] optionBgs = CurrentlyEditedNodeDropdown.GetComponentsInChildren<Image>()
    6.         .Where(go => go.name == "Item Background").ToArray();
    7.  
    8.     for (int i = 0; i < optionBgs.Length; i++)
    9.     {
    10.         optionBgs[i].color = selectedNodes[i].color;
    11.     }
    12. }
     
  5. Were_Elf

    Were_Elf

    Joined:
    Feb 25, 2022
    Posts:
    53
    upload_2022-9-2_16-19-28.png
    Yeah, I also used event listeners (The method names have been updated in the screenshot, but UpdateColor used to be ValueChanged and OnDropdownShown was just Shown).

    By the way, I tried to do it like you, but I get an error "Image[] does not contain a definition for 'Where'....". How can I enable this functionality?
     
    Last edited: Sep 2, 2022
    Matsyir likes this.
  6. Matsyir

    Matsyir

    Joined:
    Mar 13, 2019
    Posts:
    29
    Were_Elf likes this.