'Wrapped world' effect with 2 cameras?

My game is mostly played along the horizontal axis (X movement, with minimal Y movement). I want to create a looping world to create the illusion of a planet. So far, what I’ve seen in most forum responses was to create duplicates of the world in each direction, but I was wondering if it’s possible to just have duplicate cameras that would render the other side of the level as the player approached the edge, and simply rely on ‘teleportation’ (ie. position.x += levelWidth) for game logic.

Yes, that should be possible. Though it might cause problem with some shader types. What you should to is create a second camera with the exact same properties as the main camera except that you set the clearflags of the second camera to none. You can add the second camera as child to the main camera and just offset it by the worldsize either to the left or right. Keep in mind that you can disable the second camera most the time. You just need to enable it when you get close to one of the ends.

Something like this:

using UnityEngine;

public class WrapWorld : MonoBehaviour
{
    public Transform LeftEndPoint;
    public Transform RightEndPoint;
    public float WorldWidth = -1;
    public float ScreenSize = -1;
    public Camera secCam;
    public Camera mainCam;
    void Start ()
    {
        if (mainCam == null)
            mainCam = Camera.main;
        if (secCam == null)
        {
            secCam = GetComponent<Camera>();
            secCam.transform.parent = mainCam.transform;
            secCam.clearFlags = CameraClearFlags.Nothing;
        }
        if (WorldWidth < 0)
            WorldWidth = RightEndPoint.position.x - LeftEndPoint.position.x;
        if (ScreenSize < 0)
        {
            var p = mainCam.ViewportToWorldPoint(new Vector3(0, 0.5f, -mainCam.transform.position.z));
            ScreenSize = (mainCam.transform.position - p).x * 2;
        }
        
    }
    void LateUpdate ()
    {
        var d = mainCam.transform.position.x - LeftEndPoint.position.x;
        if (d < ScreenSize)
        {
            secCam.enabled = true;
            secCam.transform.localPosition = Vector3.right * WorldWidth;
        }
        else if(d > WorldWidth - ScreenSize)
        {
            secCam.enabled = true;
            secCam.transform.localPosition = -Vector3.right * WorldWidth;
        }
        else
            secCam.enabled = false;
    }
}

This of course assumes that the world is located at a world z position of “0” (normal 2d). It should work with orthographic or perspective cameras. All you have to provide to the script are markers at both ends of the world which basically should be the connection points. Make sure you attach this script to the secondary camera. As long as “WorldSize” and “ScreenSize” aren’t set explicitly in the inspector it should automatically calculate those values from the given markers. It also assumes Camera.main as main camera and the secondary camera as the camera attached to the same object as this script. However you can set those manually if you like.

This script automatically enables the secondary camera when you get close to one of the ends and positioning the secondary camera accordingly. When you actually wrap the main camera the script should detect this automatically and the two cameras basically swap places.

The simplest solution is creating 4 copies of the world and put it at the edges. As soon as your camera fully enters one edge copy of the world, both the camera and the player are transform.translated to the middle world at the respective coordinates. The difficulty with this is that you have to update the edge copies as you make changes to the main world.

This could be done better if your world was in a grid - then you could write a script which actually orders the camera to render only those blocks in the grid you need - to get grid elements, you’d just use modulo. However, this requires some preparation, and I’m not sure if your world is in a grid.

The last thing I would consider is actually quite expensive and complicated, but it can simulate a looping world very well because, well, it is a looping world. If your game is 3D, you could simple create a sphere on which you’d create your world. Then your world would truly loop. For a 2D game you’d have to go 3D, but you’d only have to apply a texture to that sphere and paste other sprite content, instead of actually building objects on a 3D model.

I think the 2nd approach is the best performance wise and the one I’d go for, but you choose.