Convert image to grid

I’ve got a (for my at least) unusual task at hand where I need to take an image and slice it into an array of small parts of that image so I can throw them around individually…
Sort of like in this video here:

Unfortunately for me, I’ve never really done anything similar so I am kinda drawing a blank here (and my google power has found nothing of value). Of course one way could be to slice it manually in a tool like Photoshop and than manually create the grid inside Unity - but this sounds highly ineffective to me and I was wondering if anyone of you guys knows perhaps of a more dynamic way.
Thanks :slight_smile:

Are you doing it on the fly in runtime? Since you mention PhotoShop, i assume that is not the case. You could always import the image as a sprite, set the sprite to multiple, use the sprite editor’s grid slicing tool and slice away. That will divide the image into several smaller sprites that can be flung around as you want to…

2 Likes

Here you go:

Also make sure you made your image Read/Write enabled

using UnityEngine;
using System.Collections.Generic;

public class SplitImage : MonoBehaviour
{
    public Texture2D exampleImage;
    public List<Texture2D> imageTiles;

    public void Start()
    {
        Split(exampleImage, 120, 120); //120, 120 is size of new tiles
    }

    public void Split(Texture2D image, int width, int height)
    {
        bool perfectWidth = image.width % width == 0;
        bool perfectHeight = image.height % height == 0;

        int lastWidth = width;
        if(!perfectWidth)
        {
            lastWidth = image.width - ((image.width / width) * width);
        }

        int lastHeight = height;
        if(!perfectHeight)
        {
            lastHeight = image.height - ((image.height / height) * height);
        }

        int widthPartsCount = image.width / width + (perfectWidth ? 0 : 1);
        int heightPartsCount = image.height / height + (perfectHeight ? 0 : 1);

        for (int i = 0; i < widthPartsCount; i++)
        {
            for(int j = 0; j < heightPartsCount; j++)
            {
                int tileWidth = i == widthPartsCount - 1 ? lastWidth : width;
                int tileHeight = j == heightPartsCount - 1 ? lastHeight : height;

                Texture2D g = new Texture2D(tileWidth, tileHeight);
                g.SetPixels(image.GetPixels(i * width, j * height, tileWidth, tileHeight));
                g.Apply();
                imageTiles.Add(g);
            }
        }
    }
}
5 Likes

:open_mouth: I didn’t knew the sprite editor could do that. Then again - I’ve never used it yet. Thanks a lot for the pointer! :slight_smile:

You, Sir, are amazing! I would have coded it myself with a few hints, but you just saved me the trouble. Thanks a lot for this!
This proves again that Unity indeed has a great community.

Np, I’m glad i could help you :slight_smile:

1 Like

So, the script works quite like it should, but unfortunately I’m getting some weird border-artefacts on the new created sprites. I’ve tried every possible texture import setting but it doesn’t seems to be afflicting it. Unfortunately I’m really inexperienced with anything related 2D, so I’m drawing a blank again. :wink: Any help is immensely appreciated!


SOLVED: So, it turns out that the image was scaled down in the viewport since it was inside the editor and for some reason that created the artefacts. Problem solved itself when rendering in standalone and fullscreen.

Basically you don’t need to slice image to tiles to output it as tiles. You can just create grid inside 3d package and then assign it uv using ortographic projection.

For one our project I made a particle system where each particle was just 1 pixel of FullHD texture. I rendered it using geometry shader (~ 2kk particles) and procedurally calculated the UV for each particle (its coordinates divided by size in idle position)

I would advise to go with this technique. Unless there’s a reason not to.

Can you share the code i need exatly that i have truble in instantiate list of array into a single image

To avoid the artifacts (i.e. strangle lines), use the Clamp WrapMode after defining the new Texture2D:

g.wrapMode = TextureWrapMode.Clamp;

How I can use the list of array to a single image or as texture? I serach around, but I dont find a solution…can someone help me?