ali10gaucho
ali10gaucho

Reputation: 41

Making an object inaccessible at runtime

I have a very specific question. I have a bunch of cubes besides each other in my scene.

When I click on one of them that cube turns red (or one the other colors in my array) for a few seconds, and this script is applied to all of my cubes.

Now what I want to happen is that as long as one of the cubes is red, the other ones are inaccessible (when I click on them they don't change color).

This is the code for my cubes:

private renderer render;

void Start()
{
    render = GetComponent<renderer>();
}

private Color[] colors = {Color.red, Color.green, color.yellow);

void Update(){}

void OnMouseDown()
{
    render.material.color = colors[Random.Range(0, colors.Lenght)];
}

Upvotes: 0

Views: 111

Answers (2)

Programmer
Programmer

Reputation: 125245

Oops... I thought I posted my answer but it didn't go through. Either way, the code is already written and I can't throw it away.

This method uses array. Change the array size from the Editor to 5 and assign 5 cubes to it. The red cube will only change color, the rest wont unless there is no red cube in the scene.

public GameObject[] cubes;

void Start()
{

}

private Color[] colors = { Color.red, Color.green, Color.yellow };

void Update()
{
    checkMouseClick();
}


void checkMouseClick()
{
    MeshRenderer tempMR;

    //Check if mouse button is pressed
    if (Input.GetMouseButtonDown(0))
    {
        RaycastHit hitInfo = new RaycastHit();
        if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo))
        {
            tempMR = hitInfo.collider.gameObject.GetComponent<MeshRenderer>();

            int cubeSize = cubes.Length;

            //Loop through all the cubes in in cubes array
            for (int i = 0; i < cubeSize; i++)
            {
                //Check if any of them have a red color
                if (cubes[i].GetComponent<MeshRenderer>().material.color == Color.red)
                {
                    //if the cube we clicked is alread read, go ahead and generate a new color for it, else DONT CHANGE THE COLOR
                    if (cubes[i] == hitInfo.collider.gameObject)
                    {

                    }
                    else
                    {
                        return; //Exit if any cube has the red color
                    }
                }
            }

            //No cube has a red color, change the color of clicked cube to a random color
            tempMR.material.color = colors[Random.Range(0, colors.Length)];
        }
    }
}

Upvotes: 0

TheLethalCoder
TheLethalCoder

Reputation: 6744

You will need to set a class level Boolean to control over when one of the cubes is red, for example:

static bool _bBlockMouseDown;

void OnMouseDown()
{
    Color color = colors[Random.Range(0, colors.Lenght)];
    if (color == Color.Red)
    {
        _bBlockMouseDown = true;
        render.material.color = color; //Force the color to be set here
    }

    if (!_bBlockMouseDown)
    {
        render.material.color = color;
    }
}

This code changes the cube to a random color and if it is red sets a Boolean to true that will block any other cubes from having their colour set. All this needs is whenever the cube is not red anymore just change the _bBlockMouseDown variable to true.

NOTE: The _bBlockMouseDown variable is static so that it contains the same value across all of the cubes.

An alternate solution to this would be to use the System.Linq namespace and have a list of the cubes. Something like the following:

void OnMouseDown()
{
    if (!listOfCubes.Any(c => c.material.color == Color.Red))
    {
        render.material.color = colors[Random.Range(0, colors.Lenght)];
    }
}

This approach has the downside that it will be slightly slower if there are a lot of cubes.

Upvotes: 2

Related Questions