IEnumerator in new thread

Hello,

I am relatively new to multithreading, therefore apologies if the answer is easy.
Currently working on a small 2d platformer and have written a fadein/fadeout effect for the camera which works just fine.

	IEnumerator camfadein() {
		for (i=0.0f;i<=1.0f;i=i+0.1f) {
			GameObject.Find ("fader").GetComponent<SpriteRenderer> ().color = new Color (0.0f, 0.0f, 0.0f, i);
			yield return new WaitForSeconds (0.01f);
		}
	}

It is simply changing the alpha value for a black tile in front of the camera, not complicated.

The problem comest that Waitforseconds() keeps lagging the character movment while this loop is running, therefore I decided to run this fading effect on a new thread.

Thread t1
.
.
t1 = new Thread (camfadein);
.
.
t1.start();

However Unity is giving me an error stating that Thread has void return type and IEnumerator is mismatched of the delegate’s(thread) return type.
Is there any way to get a workround on this?

Thank you in advance.

There are several things wrong here:

  • First of all the Unity API is not thread safe. So you can’t use any method from the API from a different thread then the main thread.
  • Unity’s coroutine’s are not methods. They are objects and tightly bound to Unity’s coroutine scheduler which resumes your coroutine at the right times. This all happens on the main thread.
  • You did a WaitForSeconds(0.01) which would “theoretically” give you 100 iterations per second (1 / 0.01 == 100). However you usually don’t have such a high framerate. So WaitForSeconds will most likely “wait” for a longer period depending on the framerate. That’s why you usually use Time.deltaTime to make things frame independent.
  • Using GameObject.Find and GetComponent each iteration is a very bad idea. Those are very slow methods and in each iteration you will get the same object. So cache it.
  • The variable “i” seems to be a member variable of your class? That’s very bad design, especially in a coroutine. for-loops should always have their dedicated local variable.
  • Method names should start with an uppercase letter. The usual guidelines are to use PascalCase

Here’s how you should implement that coroutine:

IEnumerator CamFadeIn(float aFadeTime)
{
    SpriteRenderer rend = GameObject.Find ("fader").GetComponent<SpriteRenderer>();
    for (float i=0.0f; i<= aFadeTime; i += Time.deltaTime) {
        rend.color = new Color (0.0f, 0.0f, 0.0f, i);
        yield return null; // just wait one frame
    }
}

That way your fading is time based. So you just pass the time the fading should take in seconds.

// This fade should take 0.5 seconds
StartCoroutine(CamFadeIn(0.5f));

ps: Since you’re “new to multithreading” you should better forget about it when it comes to Unity. There are only a few edge cases where using threads in Unity makes sense. In those cases you should know exactly what you’re doing ^^. Improper use of threading is the easiest way to introduce random bugs / crashes into your application. It’s better to learn about threading outside of Unity. Threading isn’t that complicated but you have to be aware of where and when you need locking / synchronising / memory barriers. If you don’t your program is no longer deterministic (and might even cause serious problems beyond it’s domain).