Tiling sprites in Unity

The current state of 2D in Unity is currently a bit underdeveloped, due to the fact it was only recently released. After all, Unity is still primarily a 3D engine. One of the obvious things that are missing right now is the ability to have tiled sprites. As of version 4.5.4, you cannot do that out of the box without some nasty trickery. Current solutions you find online will usually have you replicate a sprite multiple times, but that’s far from the best solution; a Sprite is not just an image, it’s its own entity that comes with additional overhead.

My solution to this problem is simple, as long as you follow the steps. The only drawback is that it cannot be used for sprites that belong to an Atlas, because it’s not possible to access the values of the minimum and maximum texture coordinates that are used for a Sprite draw call in the Shader. If anyone knows a way to have that information, please let me know.

Introducing Mr. Meow, our adorable kitty who is so cute that we can’t help the urge to replicate him all over the screen:

Mr. Meow

Tiling your Texture

1. Set the right Texture Import settings for your Sprite.

To do that, you need to go to the Inspector of your Sprite and change the Texture type to Advanced. After you do that, you can set the wrap mode to Repeat. You also have to change the Mesh Type to Full Rect, otherwise part of your tiled sprite will get cut off. You do not need to change any of the other settings. However, changing the Pivot to Top Left (or any other corner) might help with positioning your Sprite better, since you will have to change its size later.

2. Create a new Shader and add this code.

This was adapted from the default Sprite shader. You can make changes to it if you wish. The important modifications over the original source code are highlighted.

Note: The default sprite shader might change in newer versions, although the tiling shader should probably still work. If you find that the shader stopped working after upgrading, try downloading the default unity shaders. Then try creating a new shader based on the default sprite shader, but with the extra highlighted lines. Remember to change the name of the shader as well.

Update 29/03/2015: This shader had stopped working for Unity5. Adding the brackets at the and of line 5 fixed this problem.

Update 14/07/2015: This is a modified version of the Unity 5.1 shader.  The old shader is still working, but I suppose it’ll be safer to use this instead, for maximum compatibility.

 

3. Create a new Material with our Shader.

This step is self-explanatory, unless you never used custom Shaders before. I will assume that you know how to create a new material from project view. Name it SpriteTile or anything else you wish. Afterwards, all you have to do is select our new Shader from the drop down list.

Select Shader for MaterialAlternatively, you can drag and drop the Shader to the Material.

4. Set the Repeat X and Repeat Y values of the Material.

The default values of 1 and 1 have no effect. This defines how many times the Sprite should repeat on each axis. For example, the values 2 and 3 will make the sprite repeat 2 times horizontally and 3 times vertically. Sometimes Unity hides these settings; if you don’t see them, simply click on your Material in the Inspector.

Material Settings

5. Add this material to your GameObject

Again, pretty straight forward, but if you haven’t done that before then you simply drag our new material to the Material slot of the SpriteRenderer of our GameObject.

You might have noticed that after doing so, the Sprite DOES tile, but it is squashed within its own size.

Kitty (Before & After)

6. Change the scale of the Transform

Obviously, the next step is to change the scale of the Transform of our GameObject. What our Shader does is to simply repeat the sprite within its bounds. We will be fine if we change the scaling to the amount our Sprite repeats, or even multiples of that (for scaled down/up tiled textures).

Set the scaleNow Mr. Meow tiles as intended:

Kitty (Final)

And there you go. Real hardware tiling!

Having a tiled background

As a bonus, you might want to tile something as a background. You could figure this out by yourself, but since I have already done it for my games I’ll go ahead and post the steps for that.

1. Set your Sprite’s pivot to Top Left.

This time it’s not optional like it was in Step 1 of the previous section.

2. Add this extension class to your code.

You can alternatively put the enclosing method into any public static class, or simply have it hidden somewhere and only available for the next step. This is such a handy extension method to have around, however, so you might want to keep it like this.

 3. Add this Monobehaviour to your GameObject that contains our Material and is responsible for drawing the background.

The variable _squareSize  shows how many times the background will repeat horizontally. It will then repeat as many times as it should vertically while keeping the correct aspect ratio, starting from the bottom left corner of your screen. You can change the value of _squareSize  in the inspector (appears as “Square Size”) or just leave it a hard-coded value.

Set Square Size

The final result looks like this:

Army of KittiesNow, no matter how much you move or scale the Camera, your screen is guaranteed to always show 10 Sprites horizontally. You would probably need to set this to the background behind everything else. An easy way to do this is to set the Sorting Layer to something else that is behind the default layer. I’ll let you do this yourself.

Happy tiling!

Demo (01/02/2016):

I have put together a small demo that demonstrates the tiling. You can refer to it if you have issues getting it to work. Link here.

18 thoughts on “Tiling sprites in Unity”

  1. Does this still work? I tried implementing it but didnt find the options for step 1. After setting the texture to advanced, the settings have been changed :/ Dang it! Oh well, thanks anyway 🙂

  2. I’m not sure if it works with Unity 5.1. The shader makes the material bright pink, which, if my limited experience in Unity is correct, indicates an error,

    1. Hello,

      I have tried it with Unity 5.1 and it seems to be working. I put up a newer version as well which uses a modified version of the Unity 5.1 shader (which changed slightly from previous versions). You can try that and tell me if it worked.

      I’m not sure what’s wrong, make sure you followed the steps correctly.

      Charis

  3. Hi Charis,

    I was using your solution for tiling sprites in Unity and it work perfectly but I have a problem when I build my game for Android platform. In PC version I can see all the sprites repeated perfectly but when I build in Android version the tiling is not working! The sprites are not repeating.

    Do you know why is it occurring? Could you help me, please?

    Thanks in advance!
    Santi.

    1. Hello,

      The shader should work on mobile. In fact, I’ve already used it in an android game. However, I do remember having an issue with a different shader, when I performed operations between different types (e.g. float + fixed, or *something* like that). If I remember correctly, the same code even worked fine on a different device.

      In my shader, for some reason, I was creating a float2 on line 58 and multiplying it with a half2. That might be the issue. I changed the code there, you can try it again. Please tell me if it worked!

      If it didn’t work, try running my game on your phone, built with Unity 4.6: https://play.google.com/store/apps/details?id=com.surewash.handymd&hl=en
      The in-game background there is tiling with the same shader (I don’t remember if it’s identical or not, but it’s the same logic), so if it works then using this shader yourself shouldn’t be an issue.

      If your tiling still doesn’t work and the game works fine, it probably means you didn’t follow the steps correctly.

      Please let me know how it goes!

      Charis

      1. Hi again Charis, sorry for my delay. I have to say to you that even with the last version of your shader I have the same problem when I load the project in Android platform mode 🙁 I would like to show you a snapshot but I think I can’t inside this comment… Could you tell me a email address where I can to send yo the image, please? Thanks in advance.

        1. Hi, do you get the image at least once? I have updated the post to include a small demo that works for me. If the demo doesn’t work for you I don’t know how I can help you.

          Keep in mind that Unity 5.4 (which is due to be released this March) will finally include built-in tiling.

          Charis.

          1. Hi! I have already found the problem! It was not working because the tiled image was not POT (power of two) and some mobile devices have problems. Anyway I will test your demo. Thank you for your help! 🙂

  4. Hi Charis,

    I’m trying to figure out how to get your shader to work with a sprite sheet. I want to tile a region, and have each tile animate.

    Unfortunately, when I use a sprite sheet as the sprite, the entire sheet repeats. I’ve tried having just the first frame of the sprite draw, by using material.SetTextureScale() and material.SetTextureOffset(), but they seem to have no effect.

    Any ideas?

    Thanks,

    Tim

    1. Hi,

      Unfortunately, this doesn’t work for a sprite atlas. In order to make it work, you’d need to know the size of the atlas and the size of the sprite you want to tile (in the atlas). However, Unity 5.4 (which is due to be released this March) will finally include built-in tiling, which will probably solve this problem.

      Charis

        1. You might still be able to do it by using a custom Sprite Packer Policy that always puts sprites in a predictable position in the atlas, but I don’t know as I’ve not used that feature before and it gets too complicated to be worth the trouble.

  5. Hey Charis,
    I am very new to dealing with shaders. I am using your tile shader to create a hexagon background and it works pretty good. My test device is samsung s3 mini, and when I used the shader you provided to create differently coloured 3 similar maps, the performance is decreased dramatically (Because they overlap a lot). So, I need to find a way to tweak the shader so that, for example, first 3 top, bottom, left and right repetitions will be tilted to red, between 4th and 8th repetitions from top, bottom, left and right will be tilted to yellow and the remaining middle part will not be tilted. How can I achieve such effect?

    Thanks man, keep up with the good work ! 🙂

Leave a Reply