Simple Timer Script Question

I’m trying to start a timer on a gameobject when it is deactivated, after the allotted amount of time it is reactivated. here’s what I wrote so far.

using UnityEngine;
using System.Collections;

public class Rotator : MonoBehaviour 
{
	public float myTimer=5.0f;

	// Update is called once per frame
	void Update () 
	{
		transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
	}
	void OnDisable()
	{
		if (myTimer > 0f)
		{
			myTimer -= Time.deltaTime;
		}
		else
		if (myTimer <= 0f)
		{
			gameObject.SetActive(true);
		}
	}
}

The problem lies when I deactivate the GameObject the timer goes down from 5 to 4.98 and no more. Also I don’t think the command to make it reappear is functioning as well.

My other question is there anything I need to add to the script so it is recurring, so everytime the object is deactivated this script will activate or do I need add something else.

Thanks.

As you have noticed, OnDisable is not recurring. You need to use a recurring function, normally you would use Update or a Coroutine but both of these are disabled when the gameObject is disabled. One option would be to use InvokeRepeating,

But for what you are doing it makes more sense to just use Invoke

using UnityEngine;
using System.Collections;
  
public class Rotator : MonoBehaviour { 
     void Update ()  {
         transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
     }
     void OnDisable(){
         Invoke("Enable", 5);
     }
     void Enable(){
         gameObject.SetActive(true);
     }
 }

OnDisable only gets called once, when the object is disabled, so you can’t use a timer there. And Update gets disabled when an object is not active.

One solution is to have another game object that stores a reference to your rotating object, and controls whether it is active or not.

ROTATING OBJECT

public class Rotator : MonoBehaviour {
     void Update () 
     {
         transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
     }
 }

CONTROLLER OBJECT

public class RotatorController : MonoBehaviour {

public GameObject rotator; //drag the rotator object into this variable in the inspector

public void DisableRotator(){
		rotator.SetActive(false);
		StartCoroutine(ActivateRotator());
	}
	
IEnumerator ActivateRotator(){
		yield return new WaitForSeconds (5f);
		rotator.SetActive(true);	
	}

 }

Then you just need to call the DisableRotator() function when you want to deactivate/activate your object.

I believe it’s because OnDisable() is only called once and when the GameObject is disabled, it can not do anything and will act like it doesn’t exist. You would have to use another GameObject to control the one that is being disabled.

Just put this code in another GameObject and put the GameObject you are trying to control in this script’s “go” variable. It should do exactly what your code did plus what you want it to do.

    public GameObject go;
    public float myTimer = 5.0f;

	void Start () {
        if (!go)
            Debug.LogError("There is no GameObject to control");
	}
	
	void Update () {
        if (go.activeSelf)
        {
            go.transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
        }
        else
        {
            if (myTimer > 0F)
            {
                myTimer -= Time.deltaTime;
            }
            else if (myTimer <= 0f)
            {
                go.SetActive(true);
                myTimer = 5.0F;
            }
        }
	}

I just tested it so it will work as long as you add it correctly. It will rotate your GameObject until it is disabled then when it is disabled it will reenable it after 5 seconds and the cycle will restart.