Simple problem, complex description

Hi.

Trying to do something in 2D and I’m stuck.

I have made letters A and B in Photoshop. It has a fill image and a Outline image.
I have a button on scene. When I click the button I want to color all letters Fill image with a color.

So my question is how I can color all letters fill color at once?

What I don’t understand is how I can reference several instantiated prefabs image childs called “Fill”?


What I mean, since both letters have the same children. Images called Fill and Outline.
Can I somehow do
variable=“fill”
variable.color = code.
to fill all selected letters fill?

Because Im stuck at fill.color = code but fill is explicitly assigned in the inspector
and I need it to be in script instead and I cant figure it out.

Maybe you can find them by tag or type and add them to an array:
GameObject[ ] list1 = GameObject.FindGameObjectsWithTag(“Fill”);
GameObject[ ] list2 = GameObject.FindObjectsOfType();

Then do: foreach(GameObject go in list1) { go.color =…

When they’re instantiated, keep track of them in a list. You can either use the GameObjects or the transforms of these, or if that’s a more generalized setup, you could turn it into a prefab and have a component that knows about the prefab’s structure and resolves the references. You could then just keep track (or search for) the component types (which abstract everything) and call a function on it. The component would then take care of whatever it was designed to do - it’s the implementation detail and the caller (the method that is linked to the onClick of the button) would no longer need to know any details directly.

Sorry for that very abstract description, but perhaps that’s already enough for you to get on the right track.

Tried something like that but GameObject don’t have .color attached. I don’t know how to color a GameObject.

Suddoha.
Here is what I’m trying to re-create. http://www.graffiticreator.net/htm/creator_kodiak.htm
So back in 2000 or so I coded that thing in ActionScript. I don’t even remember what base language that way, haven’t coded since then so now when I pick it up again I’m starting from scratch.

Anyways, so if I wanted to put colors on all letters elements named “fill”
Then I could type

variableName = “fill”;
letter[0][variableName].color = soAndSo…

As I understand it you can’t replace part of a path in the same way in c#.
So really, I am completely lost on how people usually do this. How would you go about targeting several letters specific image? Or maybe that is the wrong way to start…maybe I shoulnd’t put images inside a GameObject, what else?

Oh that example is alot more advanced than I imagined.

Anyway, it’s basically still the same as if you only had 2 parts to fill.

So, since you’re dealing with 2D, you’ll have all these SpriteRenderer components attached to your objects. That’s the access point you need to get to, as they’re responsible for manipulating the appearance of the sprite.

You can get the renderer component by using GetComponent or more specifically, GetComponent().
If you’ve setup everything to be in a hierarchy, you could just use GetComponentsInChildren<…> (note the ‘s’ for plural). You may then want to sort them depending on their tag, name, any appendix or however you like to ensure you build lists of certain parts (top, bottom…)

It’s worth reading the documentation. Often, you can also guess which properties are available by looking at the inspector of a component. For instance, in order to set the SpriteRenderers color, you can get the component like mentioned above and access the color property (.color).

The remaining logic is pretty straight forward using solid colors: Get the array or list of renderers you want to apply the color to and use a for (or foreach) loop to iterate that array/list and set the color.

For some more advanced effects like the gradient and such, it might be better to look into shaders (unless you’re satisfied with the not-as-flexible variants using textures).

Another (perhaps a better?) approach is the one I described above.
Write a component that resolves all the parts of a letter (i.e. it’s renderers) and expose some more decriptive methods.
The access of the renderers remains the same, it’s just structured a little differently.

Ok thank you very much Suddoha,

I’ll read up on it. thx.

Quick question.

I currently have my different elements i.e Fill, Outline, Bubbles and so on each on Images.
When I have them on Images then Sprite renderer doesn’t apply any color because it seems that the component Image/Color will override it.

Is there a workaround for this or should I instead put my images on Sprites or something else?

If they are sprites, use GetComponent().color
If they are UI images use GetComponent().color
You can easily keep the gameobjects in a list when you instantiate them and then set colors

1 Like

This should actually work. The color adds an overall tint to the sprite. If you use white sprites, they should be colored correctly. You can test this by creating a new sprite and assign one of the default sprites to it, then just change the color in the inspector. It should change the color accordingly.

*Edit Reading @mahdiii 's post, I just realized you might have used UI images. I’d just switch to sprites instead.

Yea I tested that before, all my elements are solid whites.
However it doesnt work because in run mode I see that I Do color the Sprite renderer but nothing happens because the other component in Image / color, that one overrides it it seems. I can always remove that component I guess.

In any event. I wont get nowhere before I figure out how to Reference a specific image inside my GameObejct when I instantiate it :slight_smile:

How do I reference my “fill” image located in a GameObject that is my Prefab, which I instantiate?
I get the reference error, I don’t want to explicitly link them in the inspector because I don’t know which letters comes out…
If you understand what I mean.

I did this guy,

letter.newLetters[0].GetComponent().color = new Color32 ((byte)sliderRed.value, (byte)sliderGreen.value, (byte)sliderBlue.value, (byte)sliderAlpha.value);

letter is the Class where I Instantiate my prefab letters.
newLetters is the empty list I push in the created letters.

And this give me a reference error. So I don’t know how to get around that.

We’ve already told you to use GetComponent call. You need to speak to the renderer, so to say. It’s the component responsible to change the sprites appearance.

*Edit Posted at the same time :stuck_out_tongue:

First of all, as I mentioned earlier, use sprites instead of images.
Next, as stated above, you have to tell the renderes to change the color.

I know you said it but I’ve tried using sprites instead of images and for a reason I don’t know, they turn invisible.

I instantiate like this:
GameObject letterA = Instantiate (letter [0], new Vector2 (0, 0), Quaternion.identity);
newLetters.Add (letterA);
newLetters [0].transform.SetParent (GameObject.FindGameObjectWithTag (“canvas”).transform, false);

And I see it pop up inside my canvas but invisible. position is 0,0,0.
Know why that is?

And…if I get it visible again the reference is still broken.
I hit my color button.

letter.newLetters[0].GetComponent().color = new Color32 ((byte)sliderRed.value, (byte)sliderGreen.value, (byte)sliderBlue.value, (byte)sliderAlpha.value);

the error: NullReferenceException: Object reference not set to an instance of an object

Do I have to explicitly link it in the inspector?

I read most of this thread. I have a question. Say you just put 1 sprite (or image) in the game, and try to change it’s color value (even just in Start(), for testing), can you get that done?
1 problem at a time :slight_smile:

  1. Sprites don’t need to be a child of a canvas. A canvas is the root object for a hierarchy of UI elements. That’d be only necessary if you used UI Images.

  2. It does work without explicit linking.

  3. Post the complete error message and if possible, the complete script as well.