Wait 1 sec between switching textures

Hi,

I’m new to scripting and I’ve read many threads but I couldn’t figure out a solution for this.
I have two textures and I want to switch them every 1 second.
It should be like the code below, but for some reason “waiforseconds” doesn’t work for me at all!!
I want these textures switch continuously and not just 1 time. I know that I should have probably put the code in update function but placing it inside update doesn’t work neither.

    public Texture2D tex01;
    public Texture2D tex02;

    void Start()
    {
        renderer.material.mainTexture = tex01;
        yield return new WaitForSeconds(1);
        renderer.material.mainTexture = tex02;
        }

Then I thought maybe I should use IEnumerator, and I wrote this. But it doesn’t work again.

    public Texture2D tex01;
    public Texture2D tex02;

    void Start()
    {
        renderer.material.mainTexture = tex01;
        wait ();
        renderer.material.mainTexture = tex02;
    }


    IEnumerator wait()
    {
    yield return new WaitForSeconds(1);
  
    }

I’d appreciate if you could tell me what’s wrong with my code.

Thanks,
Hadi.

You’re calling the coroutine wrong. You can either make Start a coroutine by assigning it as an IEnumerator or you can call your wait coroutine by using StartCoroutine(IEnumerator);

try

IEnumerator Start()
{
    //note you should not call renderer.material multiple times as this will create instances.
    //Instead call once and store as a variable.
    //Also it might be better to use renderer.sharedMaterial.
    //This uses the material that is stored in your database instead of creating an instance.
    //You'll save on draw calls and memory but this doesn't work if you have multiple objects
    //using this material but only want to change one version of it.
    //Also note that changing sharedMaterial actually changes the asset and changes will
    //persist after you stop the game in the editor.
    Material mat = renderer.material;
    mat.mainTexture = tex01;
    yield return new WaitForSeconds(1.0f);
    mat.mainTexture = tex02;
}

or

void Start()
{
    //Stuff
    StartCoroutine(Wait());
}

I changed the code. But it seems that it doesn’t wait and when I start the game, it quickly jumps to the last texture and stays there,
And how can I store renderer.material as variable? Could you please give me some clues?

public class texturechange : MonoBehaviour {
    public Texture2D tex01;
    public Texture2D tex02;
    public Texture2D tex03;
  
    void Start()
    {
        for (int i = 0; i < 1000; i++)
        {
            renderer.sharedMaterial.mainTexture = tex01;
            StartCoroutine(SwitchWait());
            renderer.sharedMaterial.mainTexture = tex02;
            StartCoroutine(SwitchWait());
            renderer.sharedMaterial.mainTexture = tex03;
            StartCoroutine(SwitchWait());
          
        }
      
    }
  
  
  
    IEnumerator SwitchWait()
    {
        yield return new WaitForSeconds (1);
    }
}

So starting a coroutine in Start that just waits isn’t going to do anything to delay the rest of Start.
A coroutine runs alongside the routine that started it so what you’re doing there is just starting a ton of coroutines that are all running in tandem but not actually doing anything. Look at the first bit of code I posted where I turned Start into an IEnumerator. If you really want to run a separate coroutine from Start then you need to place all the code dependent on that waiting within the coroutine try:

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

IEnumerator SwitchWait()
{
    Material mat = renderer.sharedMaterial;
    mat.mainTexture = tex01;
    yield return new WaitForSeconds(1.0f);
    mat.mainTexture = tex02;
    yield return new WaitForSeconds(1.0f);
    mat.mainTexture = tex03;
    yield return new WaitForSeconds(1.0f);
}

As I said, though, if Start isn’t doing anything else then you could simplify this by using:

IEnumerator Start()
{
    Material mat = renderer.sharedMaterial;
    mat.mainTexture = tex01;
    yield return new WaitForSeconds(1.0f);
    mat.mainTexture = tex02;
    yield return new WaitForSeconds(1.0f);
    mat.mainTexture = tex03;
    yield return new WaitForSeconds(1.0f);
}

Unity will detect that Start is an IEnumerator rather than a void and run it as such. (Pretty sure Start is the only base function that can do this, just FYI).

1 Like