CLONING COLORS QUEST: ‘Light 'em Up’ - Solutions

Quest: Cloning Colors Quest
Challenge: Light 'em Up

Feel free to share your solutions, ideas and creations below. If you get stuck, you can find some ideas here for completing this challenge.

This is my solution for the first challenge.
I created an enum with 3 option, and in the Start method I created a switch case that check which option was selected

using UnityEngine;

public class ColorChanger : MonoBehaviour
{
    private SpriteRenderer mySpriteRenderer;
    private Color colors;
    private enum colorChangeEnum
    {
        red, yellow, blue
    }
    [SerializeField] private colorChangeEnum color;
    void Awake()
    {
        mySpriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Start()
    {
        switch (color)
        {
            case colorChangeEnum.red:
                colors = Color.red;
                break;
            case colorChangeEnum.blue:
                colors = Color.blue;
                break;
            case colorChangeEnum.yellow:
                colors = Color.yellow;
                break;
        }
        mySpriteRenderer.color = colors;
    }
}
3 Likes

My code was very similar. Although for some reason I was having trouble getting my enum to show up in the Inspector, even if it was a Serialized field.

First i created an array of possible colors. Those are referenced by int from other gameObjects. And can be set inside the inspector with a range slider.

    private SpriteRenderer _mySpriteRenderer;

    [SerializeField] private Color[] availableColor = new[] {Color.blue, Color.red, Color.yellow};
    [SerializeField][Range(0,2)] private int chosenColor;

    public Color[] GetAvailableColor => availableColor;
    public int SetChosenColor { set => chosenColor = value; }

void Awake()
{
    _mySpriteRenderer = GetComponent<SpriteRenderer>();
}

Set the Renderer to the chosenColor in start.

    private void Start()
    {
        if(_mySpriteRenderer != null)
            _mySpriteRenderer.color = availableColor[chosenColor];
    }
2 Likes

How did you have your enum defined? If outside of the class, it should be declared public:

public enum MyColor
{
    Red,
    Yellow,
    Blue
}
1 Like

I did get the enum working eventually but I can’t remember how. :slight_smile: I thought I had it declared as public all along, but maybe not. It’s been a while since I did this quest. Thanks for the feedback though!

My solution was very much alike. @mystic_mill you can make a variable with the type of the enum clase. Makes it so you can SerializeField it. public works to i guess tho lol

enum ColorToBe { red, blue, yellow}

[SerializeField] ColorToBe color;
1 Like

Initally I went the Enum route as that seemed easiest and less prone to errors when setting the three colors and assumed they wouldnt change.
I also went for an [ExecuteInEditMode] so I could see the color changes in edit mode without having to press play. This worked mostly.

I then decided I wanted the designer to have more options so centralised the colors to a ColorManager and an array of colors and my ColorChanger script to have a serialized int colorNo and would call the ColorManager to get current color from said array.
I also included an OnValidate which would call the ColorManager and make sure the int was valid

I then felt a need to see the colors as you chose them for the colored objects and decided a window would be a nice way may be and certainly a learning curve.
A Brackleys tutorial vid helped with the bonus of changing multiple selected objects at the same time.
Even managed to add an undo kind of. (Only of which I was aware from one of the RPG courses - ta Sam).
Still tweaking but it works well enough for me though not helped that I introduced 3D objects into my game so that involves Materials rather than just colors…

I use various Gameobject Brushes (part of the Tilemap 2Dextras set up) to paint on my colored objects.
These show up white. I then select as many as I want and Colorize them from my window and it automatically changes the color.

1 Like

I refactor my code a little

public enum ColorSelect
{
    Red,
    Yellow,
    Blue
};

public class ColorChanger : MonoBehaviour
{
    [SerializeField] private ColorSelect colors;
    private SpriteRenderer mySpriteRenderer;

    void Awake()
    {
        mySpriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Start()
    {
        AssignColor();
    }

    private void AssignColor()
    {
        switch (colors)
        {
            case ColorSelect.Red:
                mySpriteRenderer.color = Color.red;
                break;
            case ColorSelect.Yellow:
                mySpriteRenderer.color = Color.yellow;
                break;
            case ColorSelect.Blue:
                mySpriteRenderer.color = Color.blue;
                break;
        }
    }
}
1 Like

I defined enum as hexcolor that provide dropdown selection in unity editor.

using UnityEngine;


public enum PresetColor
{
    Red = 0xFF0000,
    Green = 0x00FF00,
    Blue = 0x0000FF,
    Yellow = 0xFFFF00
}
public class ColorChanger : MonoBehaviour
{
    private SpriteRenderer mySpriteRenderer;
    public PresetColor col;


    void Awake()
    {
        mySpriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Start()
    {
        Color theColor;
        if (ColorUtility.TryParseHtmlString(col.ToString(), out theColor))
        {
            mySpriteRenderer.color = theColor;
        }

    }
}

1 Like

Interesting - not come across ColorUtility before

I have an enum containing colour names and a SerializedField enum instance for selecting one as a dropdown in the inspector. Then I have an array of colours where the index correlates to the enum, allowing me to set the renderer colour by just casting the enum selection to an int.

    private SpriteRenderer mySpriteRenderer;
    
    private enum colourOptions {Red=0, Yellow, Blue};
    private Color[] colours = new Color[] {Color.red, Color.yellow, Color.blue};
    [SerializeField] colourOptions selection = colourOptions.Red;

    void Awake()
    {
        mySpriteRenderer = GetComponent<SpriteRenderer>();
        mySpriteRenderer.color = colours[(int)selection];
    }

I ended up using an array of colors + bools to select the color in the inspector. :slight_smile:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColorChanger : MonoBehaviour
{
    private SpriteRenderer mySpriteRenderer;
    public UnityEngine.Color[] colorChoice = new UnityEngine.Color[] { Color.red, Color.yellow, Color.blue };

   
    [SerializeField] bool red = false;
    [SerializeField] bool yellow = false;
    [SerializeField] bool blue = false; 

    void Awake()
    {
        mySpriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Start()
    {
     

        GetColor();
        
    }

    private void GetColor()
    {
        int count = 0;

        if (red == true)
        {
            mySpriteRenderer.color = colorChoice[0];

            count++;
          
        }
         if (yellow == true)
        {
            mySpriteRenderer.color = colorChoice[1];
            count++;
            

        }
         if (blue == true )
        {
            mySpriteRenderer.color = colorChoice[2];
            count++;
            
        }
        if(count >1)
        {
            Debug.LogError("You can only chose 1 color! Please pick either: red, blue, or yellow.");
 
        }

    }
}

I was a little bit stuck here too. I had to go back to some old code in order to remember that defining the enum as being a list of colors is step one. Having a reference to the enum in your class is step two in revealing it in the inspector.

using UnityEngine;

/// <summary>
/// List of colors to select from. Note this is global private member outside of the class.
/// </summary>
enum ObjectColor
{
    Red, Yellow, Blue, White
}

public class ColorChanger : MonoBehaviour
{
    /// <summary>
    /// Reference to color list. Initialized with something.
    /// </summary>
    [SerializeField] ObjectColor DisplayColor = ObjectColor.White;

    private void Start()
    {        
        switch(DisplayColor)
        {
            case ObjectColor.Red:
                GetComponent<SpriteRenderer>().color = Color.red;
                break;
            case ObjectColor.Yellow:
                GetComponent<SpriteRenderer>().color = Color.yellow;
                break;
            case ObjectColor.Blue:
                GetComponent<SpriteRenderer>().color = Color.blue;
                break;
            default: 
                GetComponent<SpriteRenderer>().color = Color.white;
                break;
        }
    }
}

I realize this is probably an ancient post at this point, but hope it helps :slightly_smiling_face:

I spent some time on this first question. I wasn’t happy with an Enum or a scriptable object containing a list of possible colors. I started googling for swatches & color palettes. I was disappointed to find out Unity’s native swatches can’t be used in scripts. I found a free asset and gave it a go. Made a palette with the 3 colors and used it all over the place. I was super happy with swatchr to solve this.

using UnityEngine;

public class ColorChanger : MonoBehaviour
{
    public swatchr.SwatchrColor ChosenColor; // https://github.com/jknightdoeswork/swatchr

    private SpriteRenderer mySpriteRenderer
    {
        get
        {
            if (_mySpriteRenderer == null)
            {
                _mySpriteRenderer = GetComponent<SpriteRenderer>();
            }
            return _mySpriteRenderer;
        }
    }
    private SpriteRenderer _mySpriteRenderer;

    public void RandomColor()
    {
        ChosenColor.colorIndex = Random.Range(0, ChosenColor.swatch.numColors);
    }

    private void Start()
    {
        OnValidate();
    }

    private void OnValidate()
    {
        mySpriteRenderer.color = ChosenColor.color;
    }

    private void OnEnable()
    {
        ChosenColor.OnColorChanged += OnValidate;
    }

    private void OnDisable()
    {
        ChosenColor.OnColorChanged -= OnValidate;
    }
}

Cool - well done for finding a solution that works for you.

Privacy & Terms