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!