Thursday, May 2, 2013

Orange You Happy Now



Everything was going fine until I hit the color orange.

A little background here. In order to complete a level, the player needs to pick up five bus passes. Each bus pass has associated with it two particle effects, one a rising stream of particles for the at-rest state, as pictured above, and one a sort of blooming effect on the player when the thing is picked up. Both of these are the same color as the bus pass.

The particle systems are attached to GameObjects which are then stored as prefabs. The bus pass itself is placed in the scene view with a pickup script on it, and I toggle which color this particular pass will be via the Inspector, as the list of bus pass colors is an enum within that script. When the game starts and the bus pass script runs, it looks at that variable to find out what color it ought to be, then switches to the appropriate frame of its' RagePixel sprite. Each bus pass uses the same sprite, which just has five frames of the same image in different colors.

I made the ambient particles first, and I just set the color of each directly in the particle system before making the prefab, so I ended up with five different ones like "prefab_particle_buspass_orange" and "prefab_particle_buspass_green". Each prefab was assigned to its corresponding bus pass through an inspector variable, and each pass Instantiated that prefab during its Start function. Doing it that way once was, I felt, an acceptable level of laziness, but when it came time to do the bloom effect, I decided I had better just make one, "prefab_particle_buspass_pickup_any", and then programatically change the color. After all, each bus pass knew its own color, so it should be easy enough to use a blank white material and just throw RGB colors at it at runtime.

My first "huh" moment was getting the message "UnityEngine.Color does not contain a definition for 'purple'." I must be spoiled by Unity's easy access to so many MSDN libraries, but I figured a robust suite of crayola colors in the API would be more or less de rigueur. Not the case this time, but no big deal. Since I'm using C# and Color is a Struct like Vector3, I have to remember to replace

Color purple(128.0f, 0.0f, 128.0f, 1.0f);

with

Color purple = new Color(128.0f, 0.0f, 128.0f, 1.0f);

but again, all is well, and my purple looks purple in-game! Well, a little pink but whatever. Let's try a classic Cadmium Orange:

Color orange = new Color(255.0f, 97.0f, 3.0f, 1.0f);

This comes out yellow.
Undeniably, unsquint-at-ably, absolutely damned yellow.
I thought for a while, and I spent maybe a bit too much time at Wikipedia's unusually fascinating page for the color orangeand I thought some more, and eventually I did the right thing, which is to resort to googling ever more plaintive rephrasings of one's problem and clicking on Unity Answers links until something gives.

...No, I'm kidding, the right thing to do is check the documentation, which in my case would have easily shown this, for example:

Yellow. RGBA is (1, 0.92, 0.016, 1), but the color is nice to look at!

Unity doesn't use RGBA values of 0-255, it uses normalized values of 0-1. Maybe that's a Scandanavian thing? I do like the consistency of it, Alpha is usually going to be 0-1 anyway... I tried to learn a bit more about this but I soon wandered into a forbidding land of shadows and had to turn back. Not tryng to be incurious here, but your basic safety orange should not require post-graduate math.

Unfortunately my "what if this works" first stab of just dividing each of the values by 255.0f gives us roughly

Color orange = new Color(1.0f, 0.3803f, 0.5019f, 1.0f);

Which renders onscreen as a sort of ill salmon color. Then suddenly, in the next tab, a light shone upon me, for the good people of Unity had, by their own divine providence, thought to include a built-in function to do this exact thing.

Moments later I had

Color orange  = new Color32(255, 97, 3, 255);

Which pops out blazing orange. I believe it was Ben Franklin who said, "I only try to understand something complicated until I figure out something simpler that will allow me to stop trying to understand the more complicated thing." As for the mystery of why my totally wrong purple was somehow sort of purple, I guess if you overflow the bounds of whatever kind of structure Color is, it just holds the max value, like a cup of coffee being filled by someone who has fallen asleep. (128, 0, 128, 1) is to Unity the same as (1, 0, 1, 1), which is Magenta, which looks sort of like purple, in a certain light.

No comments:

Post a Comment