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.
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?
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.
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).