Looping a coroutine for a texture flashing

Hi everyone :slight_smile:

I’m asking for help on a particular issue.

I want to have a cube, which is grey to begin, and we wait on that for a random amount of time between 6 & 7 seconds.

I then want the coroutine to kick in and cause a checkerboard flash between 2 textures for 2 - 3 seconds.

I then want it to go back and repeat this kind of pattern. A finite state machine was recommended to me but I’m at a total loss where to begin - started learning a month ago for a project and I’m in way over my head. The code I have is here (apologies for it being so all over the place). If anyone can tell me how to alter what I have to make it do what I want,I’d be grateful. :slight_smile:

public class FSM : MonoBehaviour {
   
    public float freq ; // this is a Period. We convert to freq on line 23
    public Texture[] textures; // texture 1 and 2 declared here
    void Start ()

    {

        StartCoroutine (DoTextureLoop ()); //Begins the loop

    }

     IEnumerator DoTextureLoop(){
        int i = 0;
        while (true) { //while the i = 0, we render the first texture. When it changes to 1, swap textures.
            GetComponent<Renderer> ().material.mainTexture = textures [i];
            i = (i + 1) % textures.Length;

            yield return new WaitForSeconds (1f / freq);

        }
    }

       
void Update () {
        if (Time.deltaTime > 10) {
            StopCoroutine (DoTextureLoop () );
        }

    }
       
    }

Here’s kind of a simple way to do it, all as a single coroutine. See attached package.

These sorts of little “looping behaviors” are pretty easy to do in coroutines if you break down the steps of what you’re looking for, and I think the code should be pretty self-explanatory.

Launch the given scene and watch the cube behave.

public class TimerPattern : MonoBehaviour
{
    public Texture gray;
    public Texture[] checkers;
    public float flashRate = 10.0f;
  
    void Start ()
    {
        StartCoroutine (DoTextureLoop ());
    }

    IEnumerator DoTextureLoop(){
        int i = 0;
        Renderer rndrr = GetComponent<Renderer> ();
        while(true)
        {
            rndrr.material.mainTexture = gray;
            yield return new WaitForSeconds( Random.Range ( 6.0f, 7.0f));
            float limitTime = Random.Range ( 2.0f, 3.0f);
            for (float t = 0; t < limitTime; t += Time.deltaTime)
            {
                int whichChecker = (int)(Time.time * flashRate) % checkers.Length;
                rndrr.material.mainTexture = checkers [whichChecker];
                yield return null;
            }
        }
    }
}

2227783–148395–TimerPattern.unitypackage (15.1 KB)

1 Like

This makes so much sense - I see exactly what you mean! :smile:
I forgot to declare I wanted the gray colour and for how long. Argh!
Thank you so much for your help - you’ve helped out so much!

You’re welcome. You gave very specific instructions, which is the first (and most important) part to solving a problem.

As you build your vocabulary of code instructions, you will be able to translate more and more that description into actually functioning code. Keep at it!