ali10gaucho
ali10gaucho

Reputation: 41

can't use WaitForSeconds with OnMouseDown

I used OnMouseDown() to deactivate an object but i want the object to activate again in a few seconds. I have used WaitForSeconds() for other things but this time it just doesn't work

this is what i could gather by researching (the deactivating part works fine):

void Start()
{
    StartCoroutine(wait());
}

void Update(){}

void OnMouseDown()
{
    gameObject.SetActive(false);
}

IEnumarator wait()
{
    yield return new WaitForSeconds(3);
    gameObject.SetActive(true);
}

Upvotes: 0

Views: 1385

Answers (3)

Programmer
Programmer

Reputation: 125275

There are too many reasons your code isn't work right. You are doing it backwards. Your coroutine starts immediately when your program starts because wait() is called from the Start() function. When it starts, it pauses for 3 seconds and set your GameObject to SetActive(true);

If your GameObject is already visible to the screen, your code wont do anything because SetActive(true) will be called even when it is visible. If you fail to press/click on the screen before that 3 seconds, you wont be able to see SetActive(true); because your coroutine code would have finished running by that time.

Also, if you disable a GameObject, the coroutine attached to it will stop. The solution is to create a reference of the GameObject you want to disable then use that reference to disable and enable it from another script without problems.

Since provided a code, I fixed/re-wrote it for you. I replaced the OnMouseDown fucntion with something more robust.

All you have to do is create an empty GameObject. Attach this script to that empty GameObject. Then drag and drop that GameObject you want to disable and enable to the this "Game Object To Disable" slot in this script, from the Editor.

Do NOT attach this script to that GameObject you want to disable and enable.

Tested with cube and it worked.

using UnityEngine;
using System.Collections;

public class ALITEST: MonoBehaviour
{
    //Reference to the GameObject you want to Disable/Enable
    //Drag the Object you want to disable here(From the Editor)
    public GameObject gameObjectToDisable;

    void Start()
    {

    }

    void Update()
    {
        //Keep checking if mouse is pressed
        checkMouseClick();
    }

    //Code that checks when the mouse is pressed down(Replaces OnMouseDown function)
    void checkMouseClick()
    {
        //Check if mouse button is pressed
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit hitInfo = new RaycastHit();
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo))
            {
                //Check if the object clicked is that object
                if (hitInfo.collider.gameObject == gameObjectToDisable)
                {
                    Debug.Log("Cube hit");
                    StartCoroutine(wait()); //Call the function to Enable/Disable stuff
                }
            }
        }
    }

    //This value is used to make sure that the coroutine is not called again while is it already running(fixes many bugs too)
    private bool isRunning = false;

    IEnumerator wait(float secondsToWait = 3)
    {
        //Exit coroutine while it is already running
        if (isRunning)
        {
            yield break; //Exit
        }
        isRunning = true;

        //Exit coroutine if gameObjectToDisable is not assigned/null
        if (gameObjectToDisable == null)
        {
            Debug.Log("GAME OBJECT NOT ATTACHED");
            isRunning = false;
            yield break; //Exit
        }
        gameObjectToDisable.SetActive(false);

        //Wait for x amount of Seconds
        yield return new WaitForSeconds(secondsToWait);

        //Exit coroutine if gameObjectToDisable is not assigned/null
        if (gameObjectToDisable == null)
        {
            Debug.Log("GAME OBJECT NOT ATTACHED");
            isRunning = false;
            yield break; //Exit
        }
        gameObjectToDisable.SetActive(true);
        isRunning = false;
    }
}

Upvotes: 1

Jerry Switalski
Jerry Switalski

Reputation: 2720

You cannot deactivate GameObject and continue Coroutine on it. If you deactivate GameObject that has runing Coroutine it will be stoped.

So if you want to do it right, you need Coroutine runing on other GameObject and from there actvating this GameObject.

If you need more help, ask.

Upvotes: 0

NullEntity
NullEntity

Reputation: 152

Because you're calling StartCoroutine() in Start(), your coroutine will resume 3 seconds after the component is started. You want to call StartCoroutine(wait()) in OnMouseDown() so the GameObject will become active after that.

Upvotes: 0

Related Questions