Compare a random color generated to the color of a ball from live video

Hi everyone,

I am new to Unity and c# programming and I am having some difficulties to write a code that allows me to compare a random color generated to a color of a foam ball in a live video from my webcam. If the person picks the foam ball with the same color as the random assigned and show it in the video, appears a text saying “correct” and new random color is generated, if not it waits until the colors match.

Ideally it would compare the live ball color and match it to the one with less difference among the random pool of colors and then check if this color is the one it was supposed to be picked or not. I already have a script to show the live camera placed in a GameObject and it works fine.

I’ve putted some texts showing on screen to help the person using to keep track of what color they are supposed to pick and defined a limit of 5 balls, for example. Also, the colors I placed on the script are the ones I have foam balls available.

I’ve written a code with what I little understand and could find online, but it is not working, nevertheless I will place it here so that anyone can have a better idea of what I mean, even though it most likely to be completely incorrect.

The script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using TMPro;

public class ColorGenerator : MonoBehaviour
{
    // Array of colors
    private string[] colors = { "red", "blue", "green", "yellow", "purple", "pink", "brown", "orange" };

    // Center text
    public TextMeshProUGUI centerText;

    // Right text
    public TextMeshProUGUI rightText;

    public TextMeshProUGUI leftText;

    // Color index
    private int colorIndex = 0;

    // The random color
    private string randomColor;

    // The Live Camera GameObject
    public GameObject liveCamera;

    private void GenerateColor()
    {
        // Generate a random color index, excluding black and white
        int randomIndex = Random.Range(0, colors.Length);

        // Get the random color
        randomColor = colors[randomIndex];

        // Display the center text for 3 seconds
        centerText.text = $"Remove the {randomColor} ball";
        StartCoroutine(ShowCenterTextFor3Seconds());
    }

    private IEnumerator ShowCenterTextFor3Seconds()
    {
        yield return new WaitForSeconds(3f);
        centerText.enabled = false;

        // Display the right text with the color and index
        rightText.text = $"Remove the {randomColor} ball ({+colorIndex}/5)";
        rightText.enabled = true;

        // Compare the color of the ball in the live feed with the generated color
        Color detectedColor = DetectColor(liveCamera);
        if (IsColorMatch(detectedColor, randomColor))
        {
            // Display the "correct" text for 1 second
            centerText.text = "Correct";
            centerText.color = Color.green;
            centerText.enabled = true;
            yield return new WaitForSeconds(1f);
            centerText.enabled = false;

            // Check if all colors have been correctly removed
            if (colorIndex == 5)
            {
                // Load scene 5
                SceneManager.LoadScene(2);
            }

            // Generate a new color and increase the color index
            GenerateColor();
            colorIndex++;
        }
        else
        {
            // Display the "incorrect" text for 1 second
            centerText.text = "Incorrect";
            centerText.color = Color.red;
            centerText.enabled = true;
            yield return new WaitForSeconds(1f);
            centerText.enabled = false;
        }
    }

    private Color DetectColor(GameObject camera)
    {
        // Get the camera's texture
        WebCamTexture texture = camera.GetComponent<WebCamTexture>();

        // Get the color of the center pixel
        int width = texture.width;
        int height = texture.height;
        int centerX = width / 2;
        int centerY = height / 2;
        Color color = texture.GetPixel(centerX, centerY);

        // Ignore white pixels
        if (color.r > 0.9f && color.g > 0.9f && color.b > 0.9f)
        {
            return Color.clear;
        }

        return color;
    }

    private bool IsColorMatch(Color detectedColor, string generatedColor)
    {
        // Convert the generated color to a Color object
        Color generatedColorObject = new Color();
        // Compare the detected color with the generated color
        switch (generatedColor)
        {
            case "red":
                return CompareColor(detectedColor, Color.red);
            case "green":
                return CompareColor(detectedColor, Color.green);
            case "orange":
                return CompareColor(detectedColor, new Color(1f, 0.6f, 0f)); // orange
            case "yellow":
                return CompareColor(detectedColor, Color.yellow);
            case "blue":
                return CompareColor(detectedColor, Color.blue); // blue
            case "purple":
                return CompareColor(detectedColor, new Color(0.5f, 0f, 0.5f)); // purple
            case "pink":
                return CompareColor(detectedColor, new Color(1f, 0f, 0.5f)); // pink
            case "brown":
                return CompareColor(detectedColor, new Color(0.6f, 0.4f, 0.2f)); // brown
            default:
                return false;
        }
    }

    private bool CompareColor(Color detectedColor, Color generatedColor)
    {
        // Define the threshold for each RGB channel
        float threshold = 0.1f;

        // Compare the detected color with the generated color
        return Mathf.Abs(detectedColor.r - generatedColor.r) <= threshold
            && Mathf.Abs(detectedColor.g - generatedColor.g) <= threshold
            && Mathf.Abs(detectedColor.b - generatedColor.b) <= threshold;
        leftText.text = $"{ detectedColor.ToString()}";
    }
}

If anyone can help me fix it or show a better one I will be very grateful!

Thanks to everyone in advance!

When you say “it is not working”, what part isn’t working? What behavior are you getting that is incorrect?

When I press play, just shows the video and nothing else. Not even the text indicating the color.

What is supposed to call GenerateColor? This is private, so it can’t be done from outside this script and you don’t have any Start(), Update(), or Awake() functions here to call it at the beginning of time.

It is often very helpful to put Debug.Log prints in various places in your code so that you know if the code is reaching a certain function or branch of execution. It is also very helpful to print out the value of variables to see if you are getting the values you expect.

Ok! Thank you very much! I will try this out