Looping a simple Function

Hello people of Unity. Got a question to someone with an Answer. It’s simple. I have a script prepared to make a virtual pet poop ._., now what i want to do is this:

After i clean up the whole poop i want the function to repeat the process of counting down to the next poop. Here’s what i got.

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Poop : MonoBehaviour {

	private Image poop;
	public int time;
	public bool poopToggle;

	void Start () 
	{
		StartCoroutine (delaytime ());
		poop = GetComponent<Image> ();
		poopToggle = false;
	}

	void Update ()
	{
		if (poopToggle == false) {
			poop.enabled = false;
		} else {
			if (poopToggle == true) {
				poop.enabled = true;
			}
		}
	}
		
	IEnumerator delaytime()
	{
		while (poopToggle == false) {
			yield return new WaitForSeconds (5);
			poopToggle = true;
		}
	}
}

also. the moment i inserted this script in the game my unity stops cooperating after 4 seconds. Which is why i’m here, my loop is probably making the whole thing fall down.

Any time Unity freezes after adding some code the first thing to check if probably the while loop.

     IEnumerator delaytime()
     {
         while (poopToggle == false) {
             yield return new WaitForSeconds (5);
             poopToggle = true;
         }
     }

What your coroutine is doing there is telling it to start waiting for 5 seconds all the while it equals false… and since it is never going to equal true that creates an infinite wait. You don’t need a while loop for this at all:

 void Update ()
     {
         if (poopToggle == false)
         {
              poop.enabled = false;
         }
         else
         {
              poop.enabled = true;
              StartCoroutine (delaytime());                 
         }
     }
         
     IEnumerator delaytime()
     {
             poopToggle == false;
             yield return new WaitForSeconds (5);
             poopToggle = true;         
     }

Your else statement was also written wrong by the way. Check the difference above. You could of course just remove the poopToggle condition entirely and have the coroutine just set enabled directly.

  IEnumerator delaytime()
  {
          poop.enabled = false;
          yield return new WaitForSeconds (5);
          poop.enabled = true;
  }

That would do the same thing as you are doing in update with the conditions, provided you called it again when it ended. The difference is it only sets poop.enabled = false; once rather than every single frame. Whilst more efficient it isn’t going to actually make a noticeable difference but it is generally just better practice I think.

Here… I shorten down your script…

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
 
public class Poop : MonoBehaviour {
 
     private Image poop;
     public int time;
     public bool poopToggle
     {
          get { return _poopToggle; }
          set { poop.enable = value; _poopToggle = value;  }
     }
     //Added variable//
     public float lastTime = 0;
     private bool _poopToggle;
     public const float WaitTime = 5;

     void Start () 
     {
         lastTime += Time.time;
         poop = GetComponent<Image> ();
         poopToggle = false;
     }
 
     void Update ()
     {
         if (lastTime > Time.time && !poopTiggle)
         {
              lastTime += WaitTime;
              poopToggle = true;
         }
     }
 }

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Poop : MonoBehaviour {

	private Image poop;
	public int time;
	public float delay = 5.0f;
	public bool poopToggle;

	void Start ()
	{
		poop = GetComponent<Image> ();
		poopToggle = false;
	}
	void Update()
	{

		if (poopToggle == false) {
			poop.enabled = false;
			delay -= Time.deltaTime;
		} else {
			if (poopToggle == true) {
				poop.enabled = true;
				delay = Random.Range (50, 100);

			}
		}
		if (delay < 0 && poopToggle == false) 
		{
			poopToggle = true;
		}

	}
}

This script is Exactly What i was Looking For. :slight_smile: