Coroutine for moving lights pauses after each iteration
I have a few lights generated in my Start()
. Once all lights are generated and assigned colors, range, intensity, etc... I call a coroutine that moves those lights. The coroutine looks like this:
Vector3 RandomPoint() {
float screenX = Random.Range(0.0f, Camera.main.pixelWidth);
float screenY = Random.Range(0.0f, Camera.main.pixelHeight);
//float ScreenZ = Random.Range(Camera.main.nearClipPlane, Camera.main.farClipPlane);
return Camera.main.ScreenToWorldPoint(new Vector3(screenX, screenY, paintHeight));
}
Vector3[] BezierPath(Vector3 startPoint, Vector3 endPoint) {
float distance = Vector3.Distance(startPoint, startPoint);
Vector3 startTangent, endTangent;
if (startPoint.x < endPoint.x) {
startTangent = startPoint + Vector3.right * (distance / 3f);
endTangent = endPoint + Vector3.left * (distance / 3f);
} else {
startTangent = startPoint + Vector3.left * (distance / 3f);
endTangent = endPoint + Vector3.right * (distance / 3f);
}
return Handles.MakeBezierPoints(startPoint, endPoint, startTangent, endTangent, BEZIER_PATH_POINTS);
}
IEnumerator Move () {
print("Moving...");
Vector3[][] light_points = new Vector3[NUMBER_OF_LIGHTS][];
Vector3[][] light_paths = new Vector3[NUMBER_OF_LIGHTS][];
for (int i = 0; i < NUMBER_OF_LIGHTS; i++) {
light_points[i] = new Vector3[2];
//light_points[i][0] = RandomPoint();
light_points[i][1] = RandomPoint();
}
while(true) {
System.DateTime d1 = System.DateTime.Now;
for (int i = 0; i < NUMBER_OF_LIGHTS; i++) {
light_points[i][0] = light_points[i][1];
light_points[i][1] = RandomPoint();
light_paths[i] = BezierPath(light_points[i][0], light_points[i][1]);
}
System.DateTime d2 = System.DateTime.Now;
print("Calc " + (d2 - d1).TotalMilliseconds + "ms");
for (int i = 0; i < BEZIER_PATH_POINTS; i++) {
for (int j = 0; j < NUMBER_OF_LIGHTS; j++) {
lights[j].transform.position = light_paths[j][i];
}
if (i + 1 < BEZIER_PATH_POINTS) {
yield return new WaitForSeconds(0.02f);
}
}
print("End");
}
}
The problem is that after each iteration of the while
loop the lights stop moving for a noticeable amount of time. I thought that it might be caused by the first for
loop inside the while, which calls an expensive function (`MakeBezierPoints`) multiple times, but the time diff shows that that piece of code takes barely 50ms.
What is causing that pause? How could I move my lights without any noticeable pauses?
How much is "noticeable amount of time"? A second? $$anonymous$$ore? Less?
That's an eternity. You're basically limiting your game to a maximum of 20 fps. I can't tell you exactly where the delay comes from, but blocking your code in a coroutine for that long is not good. Remember that a couroutine does not run in another thread. It only gives back control to the main loop when you call yield.barely 50ms
Also: Are the lights moving in a loop? $$anonymous$$aybe it just looks like they're not moving because their end and start positions overlap?
You're making a point here. So, how would I move my lights without blocking and without limiting to 20FPS?
The lights are moving in a path calculated by a Bezier curve. The very first loop I generate 2 random points (start and end), after that I swap the starting point with the ending point, then generate a new ending point and then a new Bezier curve. That way the points move into a random path without jumping around.
What's the value for BEZIER_PATH_POINTS? I have a feeling you're creating a huge point array there. I'd try creating much fewer points on the bezier curve and do a linear interpolation between the points myself. It will require some additional effort (= code writing), but it'll probably be much less expensive performance wise.