- Home /
Continuous camera looping
Hi. I'm trying to implement the following mechanism. The camera should loop along the x axis, seeing both sides of the in- game world at the same time. Any suggestion so as to what methods I should use ?
There are certainly many alternative solutions, but I've only come across costly ones : (1) setting a circular world, with the camera rotating around the center instead of moving along the x axis, (2) creating a parallel world with the camera popping up the other side once it reached a certain coordinate.
@Harinezumi I've finally mplemented the complementary method and it works very well without boundary at 60fps, using only : camera.rect camera.aspect
Answer by Xxov3rxx · Jul 23, 2018 at 08:14 AM
I think the best way to do this is to use two cameras. Your first camera is your main camera and it moves around as necessary. There will be another second camera that is layered behind the first one that will render the remaining scene that the first camera is missing. The hard part is finding out where to place the second camera. The way you do this is you constantly calculate how close the first camera's position relative to the edge of the screen. You also need to calculate the size of the screen which would need to be in the formula somewhere. Once you figure out where the second camera should be, update its position. In my opinion that's the most optimized way to do it.
Another way you could do it would be to duplicate the whole scene when you get close to the edge and just tile the beginning of it to the end of the first tile but that could be problematic depending on what kinda game you're making and not a clean solution.
xI agree, I also think that a 2 camera approach is the best one.
I would only add some details: you will need to set the second camera's depth value higher than the first one, and possibly also set the clear flags to "depth only".
Its position will need to be deter$$anonymous$$ed as a function of the first camera's position and the size of the world, using the %
modulo operator. For example, if your world starts at x = 0, and has a length of 50, when the first camera's position is x = 52, the second camera's position is x % 50 = 2. But be careful, %
returns negative values for negative input, so you need to use a remainder function like this:
public static float Remainder (float value, float modulo) {
float remainder = value % modulo;
return remainder < 0 ? remainder + modulo : remainder;
}
Finally, a further approach is to modify the viewport rect parameters of the cameras, so that they complement each other: one goes from X = 0 to W = 0.4, the other from X = 0.4 to W = 1. This creates a composite image without using the depth parameter.
I forgot about the clear flags to depth only. That's crucial for the 2 camera approach. The hard part is the math, so I think the best approach is to really know how big your world is before trying to process the math. In addition if you have the camera move on the Y axis, you will need a 3rd camera. The 3rd camera would represent the Y axis with the same requirements as the X camera but with Y values.
One last thing I forgot to include in the original reply, is that you need to reset the main camera's position after you completely clear the bounds of the first camera's "rendering zone". This way it effectively restarts and you can keep looping forever.
What way do you think would be the cleanest ? The "depth method" of the "complementary method" ? The second one seems to be rather simple to implement.
To be honest, I'm not sure. On one hand, the complementary method definitely seems cleaner, however, I rarely experimented with viewport parameters, while having multiple cameras with different depths is standard way of rendering different "layers" of an image, and would definitely work. Finally, with the viewport method there is a chance that due to floating point (im)precision there would be a small, but visible boundary between the 2 parts.
So if you want to / have time to experiment, try the complementary method (and it also seems cleaner), but there is less risk by using the depth method as it has been tried many times.
(Basically, the idea of using the viewport parameters for this came to me while describing the other method, so I mentioned it, but I have not tried this before).