#Dropdowns and Colors

1 messages · Page 1 of 1 (latest)

muted cloak
#

Hello! I'm having lots of trouble wrapping my head around dropdowns and colors. I want to make a color selector, which lets the user pick from 5 colors and changes entity material colors respectively.

#

How do I 1) make the dropdown just a list of colors (like squares that are the color I want)? 2) How do I update the "default" color based on the color selected?

#

I'm trying to read documentation but my head is swimming.

solemn lion
#

What part of the documentation is confusing you?

muted cloak
#

Like how to access the parts of the dropdown that I actually want.

solemn lion
#

wdym by "access" exactly

#

It's up to you to map that to whatever the relevant data is

#

e.g. by using an array or list

muted cloak
#

Well I want to change the colors of the dropdown items, but they are images?

#

Or they're sprites? I can't really tell

solemn lion
#

since that's how UI Images work

muted cloak
#

Ok so myDropdown.value is the index of the selected item. I want to programmatically set the colors of the dropdown items, to use a color palette saved in the project

#

Ok I think I'm lost in the stack of objects lol

solemn lion
#

If you look at the hierarchy of the dropdown at runtime, assuming you've assigned sprite options, you will see the Image components underneath it as children

#

youi can dig into the hierarchy frtom your code and grab the one you want

#

e.g. with transform.GetChild(n)

muted cloak
#

oh where n = myDropdown.value?

#

or it could

#

i'll give it another go. thanks!!

muted cloak
#

ok so this is what i want, but i can't figure out how to do the comment

for (int i = 0; i < ColorDropdowns.Length; i++)
        {
            Dropdown dropdown = ColorDropdowns[i];
            for (int j = 0; j < dropdown.options.Count; j++)
            {
                // want to set the color of dropdown.options[j].image
            }
        }
#

like everything i read online says i need the renderer. where is the renderer in this hierarchy?

solemn lion
#

But it won't be a Renderer

#

it will be an Image component

muted cloak
#

Yes, I've got the image component

#

What I want is to change its color

solemn lion
#

theImage.color = whatever;

muted cloak
#

but dropdown.options[j].image.color doesn't exist, it says

solemn lion
#

right because as I said you should be navigating the Transform hierarchy and finding the actual Image component

muted cloak
#

ahhhh

#

lemme see

#

ok, sorry, i guess i'm still not following. so i shouldn't try changing the colors of the options via dropdown.options, i should try changing the colors by accessing the Image component of what exactly? Not the image of the dropdown itself, bc I want the options to have different colors. Not the child of the dropdown bc there are only 2 children (unless you click the dropdown, then there is a third, but even that apparently doesn't have multiple images associated with it?)

solemn lion
muted cloak
#

it feels like i access that by dropdown.options.[j].image though

solemn lion
#

it might feel like that but that's not how you do it

#

¯_(ツ)_/¯

#

I can't control your feelings

#

that's just a reference to the sprite

muted cloak
#

yes but i still don't understand what else i would do

#

what row are you talking about?

#

how do i access that?

solemn lion
#

look at the hierarchy window

#

look for your dropdown

#

when it has options, expand it to see its children

#

you will see each row is a child object inside the dropdown somewhere (possibly under another child like "Content" or something)

#

and each of those rows has an Image component

muted cloak
#

I do not see that

#

I see Dropdown with Label and Arrow as its children

#

Or if it's a TMP, I see just Label as a child

solemn lion
#

does the dropdown have any options yet?

muted cloak
#

I'll attach a screenshot

solemn lion
#

are you looking at runtime?

muted cloak
#

Game is running

#

the drop down does have options

#

but the options are in dropdown.options which is why i'm confused

#

i just want each option to be a single solid color, picked from my color palette

#

which seems possible, but i can't find the image component you're talking about. the only thing i can find, for each option, that is an "image" is really a sprite

solemn lion
muted cloak
#

yes

solemn lion
muted cloak
#

each of those is an OptionData i think

solemn lion
#

Yeah I;m saying - do it so that it has something to actually show

muted cloak
#

which has .text and a .image, though the image is really a sprite

solemn lion
#

yes that stuff is just the data

#

the .text is a string

#

ultimately that gets displayed by a UI component such as TMP_Text or Text

muted cloak
#

yes that i get

solemn lion
#

likewise .image is a sprite, which will be displayed by an Image component

muted cloak
#

and i want to change that data, in particular change the color of the image, which is actually a sprite

#

so that if i change my color palette in the future, it changes here automatically

solemn lion
#

but you don't really change the sprite

#

you change the color of the image component and it will tint the sprite

#

the sprite is an image asset basically.

muted cloak
#

image component of what though? the only image component i see is for the dropdown itself, not for the options

#

yeah, i understand that the option image being a sprite is a barrier to doing what i want. but i don't understand how else i would do what i want.

#

the only "image" i can find is the one in options

solemn lion
#

Ok so - once you click the dropdown it will create these

muted cloak
#

i don't see the children you're saying should be there

solemn lion
#

Just tested this myself

#

seems it doesn't create them until you actually expand the dropdown

muted cloak
#

oh shit that is deep

solemn lion
#

Without the template expanded

#

So now for example

#

I was able to change these colors by changing these images

muted cloak
#

and i need to make sure i don't try to access these components unless the dropdown has been clicked?

#

or like how do i make sure they're set so that they're present whenever they're clicked?

#

bc they aren't there all the time?

solemn lion
#

yeah trying to see if there's an event for when it's expanded or something

muted cloak
#

I gues OnPointerClick?

#

Just subscribe a function to that event?

solemn lion
muted cloak
#

But then it seems like it would be setting the colors every click, which is fine i guess, but not great

solemn lion
#

basically overriding dropdown and overriding those methods to get the callbacks

#

Another thing you can do is you can modify the template object

#

Basically your dropdown will have this, even at edit time

#

you could put a script in the "item" template object somewhere and use like OnEnable in it to get notified when a row is created

#

and possibly to set the color somehow?

muted cloak
#

UGH

#

lol

solemn lion
#

lol IK it's not ideal

muted cloak
#

this feels like it should trivial?

#
#

This means like override the OnPointerClick function and stuff?

solemn lion
#

I think extending the Dropdown class might be the most straightforward way here

muted cloak
#

ok i can handle that i think, at least it's good practice

#

but does that mean I make a new script or how do i do that?

solemn lion
#

yeah you make a new class that derives from DropDown

muted cloak
#

ah and attach it to my dropdown?

#

override OnPointClick or whatever it is i want to do?

#

I think i can hack a solution that way

#

a script that runs whenever that hierarchy appears

#

thanks for helping me work through this!

solemn lion
#
public class MyCustomDropdown : DropDown {
  protected override void CreateDropdownList() {
    base.CreateDropdownList();
    // do custom stuff here
  }
}```
for example
muted cloak
#

pain in the ass lol

#

yeah

muted cloak
#

buddy i am nearly in over my head, but i'm very close, i think

#
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class ColorChangingDropdown : TMP_Dropdown 
{
    public void OnPointerClick()
    {
        for (int i = 0; i < options.Count; i++)
        {
            Debug.Log("Attempting to change color " + i);
            
            Image image = transform.GetChild(2).GetChild(0).GetChild(0).GetChild(i+1).GetChild(0).GetComponent<Image>();

            image.color = PaletteManager.Colors[i*2];
        }
    }
}
#

this is my custom dropdown, but i can't tell exactly if i'm properly "overriding" the dropdown.OnPointClick

#

or if i even want to override it??

#

i don't know enough about events etc yet

#

the debug is not getting printed

#

OOP and i'm getting somewhere

#

OMG I DID IT

solemn lion
muted cloak
#

cannot believe how difficult that was lol

solemn lion
#

e.g.

protected override GameObject CreateDropdownList(GameObject template) {
  GameObject dropdownList = base.CreateDropdownList(template);
  
  dropdownList.transform.GetChild(0).GetChild(0).GetComponent<Image>().color = Color.red;
  
  return dropdownList;
}```
muted cloak
#

ah

#

interesting

#

ofc. bc i'm in the Dropdown class, I can just override exactly what i need

#

thanks!!!

muted cloak
#

hell yeah it's working as intended

muted cloak
#

i could understand, but this tiny feature has taken all day lol

muted cloak
#

one final question and this feature will be as complete as i care to make it

#

I call this to add a listener for when the dropdown gets a new value, but I'm getting IndexOutOfBounds

public void ConnectCastesToGUI()
    {
        for (int i = 0; i < Castes.Length; i++)
        {
            Debug.Log("Connecting Caste " + i + " to ColorDropdown " + i);
            MainGUIPanel.Instance.ColorDropdowns[i].onValueChanged.AddListener((v) => { ChangeColor(i);});
        }
    }

public void ChangeColor(int casteIndex)
    {
        Debug.Log("Attempting to change the color of Caste " + casteIndex + " to ");
        
        Color color = MainGUIPanel.Instance.ColorDropdowns[casteIndex].GetComponent<Image>().color;
        
        for (int j = 0; j < AntCountByCaste[casteIndex]; j++)
        {
            Ant ant = AntsByCaste[casteIndex][j];
            ant.Transform.GetChild(0).GetComponent<Renderer>().material.color = color;
        }  
    }