Reputation: 41
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
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
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
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