How to create an infinite map closed on itself?

Let’s say I have a 3x3 tiles map. How can I loop it on itself to be able to scroll it endlessly showing the same tiles? I created a representation manually added a few new game objects, is there a way to make it work with just original 9 tiles?

9752020–1395757–2024-04-05 18-01-27.zip (4.46 MB)

to do this its harder than it should be, its not so simple

you need to make extra cameras and fake the effect

I want to ask right away - are you sure you need tiles/sprites specifically? Maybe you could take a texture and just infinitely offset it? If not, then:

I think we can approach the solution purely mathematically. Essentially, you need an “infinite” grid consisting of a repeating pattern (9 of your tiles/sprites).

The example below doesn’t provide a direct solution to your problem, but you can use this idea to implement it. Here, it simply illustrates how to build an “infinite” grid of any size with a repeating pattern. Everything is done using Gizmos and, of course, is not optimized.

You can adjust the cell size:

The size of the entire field:

Field offset (while keeping the pattern stable)

Or move the field in place, exactly the mouse scroll you need

There is a simple scene in the package where you can drag this field, just make sure the Gizmos button is enabled in the Game window to visualize it there as well.

Here it is assumed that the pivot of the cell is in the bottom left corner (just for convenience with Unity’s coordinate system). Therefore, knowing the actual position of each cell and its pattern index at any given time, you can arrange your tiles based on this data. Additionally, you can create a tile pool to reuse them instead of creating/deleting them.

using UnityEngine;


public class InfinityGridExample : MonoBehaviour
{
    [Min(0.1f)]
    public float CellSize = 1;
    [Space]
    public int CellsCountX = 10;
    public int CellsCountY = 10;
    [Space]
    public int GridOffsetX = 0;
    public int GridOffsetY = 0;
    [Space]
    public float ShiftX = 0;
    public float ShiftY = 0;


    //  drag mouse stuff
    private Vector3 _mouseDownPos;
    private Vector2 _shiftBuffer;
    private bool _isMouseDown;


    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            _isMouseDown = true;
            _mouseDownPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            _shiftBuffer.x = ShiftX;
            _shiftBuffer.y = ShiftY;
        }

        if (Input.GetMouseButtonUp(0))
        {
            _isMouseDown = false;
        }

        if (_isMouseDown)
        {
            Vector3 currentMouse = Camera.main.ScreenToWorldPoint(Input.mousePosition);

            ShiftX = _shiftBuffer.x + (currentMouse.x - _mouseDownPos.x);
            ShiftY = _shiftBuffer.y + (currentMouse.y - _mouseDownPos.y);
        }
    }

    private void OnDrawGizmos()
    {
        int patternSize = 3;
        int[,] pattern =
        {
            { 1, 2, 3 },
            { 4, 5, 6 },
            { 7, 8, 9 },
        };

        float halfCellSize = CellSize / 2f;

        for (int i = 0; i < CellsCountY; i++)
        {
            for (int j = 0; j < CellsCountX; j++)
            {
                // draw cubes
                float px = CellSize * (j + GridOffsetX) + ShiftX % CellSize;
                float py = CellSize * (i + GridOffsetY) + ShiftY % CellSize;

                Gizmos.DrawWireCube(new Vector3(px + halfCellSize, py + halfCellSize, 0), Vector3.one * CellSize);


                // draw labels
                int labelOffsetX = (int)(ShiftX / CellSize);
                int labelOffsetY = (int)(ShiftY / CellSize);

                int pattX = (j + GridOffsetX - labelOffsetX) % patternSize;
                int pattY = (i + GridOffsetY - labelOffsetY) % patternSize;

                if (pattX < 0)
                    pattX += patternSize;

                if (pattY < 0)
                    pattY += patternSize;

                UnityEditor.Handles.Label(new Vector3(px + halfCellSize, py + halfCellSize, 0), pattern[pattY, pattX].ToString());
            }
        }

    }

}

9762601–1398331–3x3GirdForumPackageExample.unitypackage (3.19 KB)

1 Like

i think with this problem what is hardest its never looping the terrain, its looping the characters, its very hard to manage the positions, loop them around, keep physics consistent, make pathfinding aware that it can go through the edge of the screen etc

Yes, what you described could indeed be challenging to implement. However, the topic author did not specify what exactly they plan to do with these tiles in the future. Therefore, my response was specifically addressing that particular question.