How to make 2d sprite tiled?

I have a grass sprite, I want to scale gameobject using this sprite and tile the texture. What is the right way to do this? There’re texture offset and scale in material properties for the common renderer, but I can’t find any similar for 2d.2d,

As mentioned in my comment, I think best solution for now is to use a Quad.

See this other question for details: I'm trying to create a Tiled Sprite, what am I doing wrong? - Unity Answers

Another thing you could do is a tile map out of many sprites. This script is for a tile of 32px

#pragma strict
import System.Collections.Generic;

var mapSizeX : int;
var mapSizeY : int;

var tilePrefab : GameObject;


var tiles : List.<Transform> = new List.<Transform>(); 


function Start () {
	var i : int = 0;
	var xIndex : int = 0;
	var yIndex : int = 0;
	
	while(yIndex < mapSizeY){
		xIndex = 0;
		while(xIndex < mapSizeX){
		    var newTile : GameObject = Instantiate (tilePrefab, Vector3(xIndex*0.32, yIndex*0.32, 0), Quaternion.identity);
			tiles.Add(newTile.transform);
			newTile.transform.parent = transform;
			newTile.transform.name = "tile_"+i;
			i++;
			xIndex++;
		}
	
		yIndex++;
	}
}

To create a 2D repeating sprite, you just need to take a stretched SpriteRenderer and tile it at the unstretched size as a child. No need to create a bunch of messy textures and additional elements beyond a SpriteRenderer and some scripting magic.

EDIT: I’ve written a Unity parallaxing library that takes care of this and supports the x and/or y axis for repeated elements. Library can be found here on GitHub GitHub - ashblue/unity-2d-parallax at develop

using UnityEngine;
using System.Collections;

// @NOTE the attached sprite's position should be "top left" or the children will not align properly
// Strech out the image as you need in the sprite render, the following script will auto-correct it when rendered in the game
[RequireComponent (typeof (SpriteRenderer))]

// Generates a nice set of repeated sprites inside a streched sprite renderer
// @NOTE Vertical only, you can easily expand this to horizontal with a little tweaking
public class RepeatSpriteBoundary : MonoBehaviour {
	SpriteRenderer sprite;

	void Awake () {
		// Get the current sprite with an unscaled size
		sprite = GetComponent<SpriteRenderer>();
		Vector2 spriteSize = new Vector2(sprite.bounds.size.x / transform.localScale.x, sprite.bounds.size.y / transform.localScale.y);

		// Generate a child prefab of the sprite renderer
		GameObject childPrefab = new GameObject();
		SpriteRenderer childSprite = childPrefab.AddComponent<SpriteRenderer>();
		childPrefab.transform.position = transform.position;
		childSprite.sprite = sprite.sprite;

		// Loop through and spit out repeated tiles
		GameObject child;
		for (int i = 1, l = (int)Mathf.Round(sprite.bounds.size.y); i < l; i++) {
			child = Instantiate(childPrefab) as GameObject;
			child.transform.position = transform.position - (new Vector3(0, spriteSize.y, 0) * i);
			child.transform.parent = transform;
		}

		// Set the parent last on the prefab to prevent transform displacement
		childPrefab.transform.parent = transform;

		// Disable the currently existing sprite component since its now a repeated image
		sprite.enabled = false;
	}
}

You can use a quad combined with a script, so that multiple quads using the same material can repeat the sprite differently.

  1. On your sprite, set Texture Type to “Texture” and Wrap Mode to “Repeat”

  2. Create a new material and set the Shader to “Particles / Alpha Blended”

  3. Select your sprite as the Texture

  4. Create a Quad and size as needed

  5. Assign the new material you created to the Quad

  6. Create a new C# Script named SetTiles then assign the new script to the Quad

    using UnityEngine;

    [RequireComponent(typeof(MeshRenderer))]
    public class SetTiles : MonoBehaviour {
    public Vector2 tiling;

    void Start () {
    	GetComponent<MeshRenderer>().material.mainTextureScale = tiling;
    }	
    

    }

In Unity 5.6 theres a better way that does NOT require any coding :

  1. make sure you COULD tile your sprite
  2. in the import options set Mesh Type to “Full Rect”
  3. on the Object, change the Render Type to “Tiled”
    boom you can now scale your object and it will tile all you want ^^

Adapted from Ash Blue

using UnityEngine;
using System.Collections;

[RequireComponent (typeof (SpriteRenderer))]
public class RepeatSpriteBoundary : MonoBehaviour {
	SpriteRenderer sprite;
	void Awake () {

		sprite = GetComponent<SpriteRenderer>();
		if(!SpritePivotAlignment.GetSpriteAlignment(gameObject).Equals(SpriteAlignment.TopRight)){
			Debug.LogError("You forgot change the sprite pivot to Top Right.");
		}
		Vector2 spriteSize = new Vector2(sprite.bounds.size.x / transform.localScale.x, sprite.bounds.size.y / transform.localScale.y);

		GameObject childPrefab = new GameObject();

		SpriteRenderer childSprite = childPrefab.AddComponent<SpriteRenderer>();
		childPrefab.transform.position = transform.position;
		childSprite.sprite = sprite.sprite;

		GameObject child;
		for (int i = 0, h = (int)Mathf.Round(sprite.bounds.size.y); i*spriteSize.y < h; i++) {
			for (int j = 0, w = (int)Mathf.Round(sprite.bounds.size.x); j*spriteSize.x < w; j++) {
				child = Instantiate(childPrefab) as GameObject;
				child.transform.position = transform.position - (new Vector3(spriteSize.x*j, spriteSize.y*i, 0));
				child.transform.parent = transform;
			}
		}

		Destroy(childPrefab);
		sprite.enabled = false;

	}
}

I use this for determining the pivot of the sprite

using UnityEngine;
using System.Collections;

public static class SpritePivotAlignment {
	public static SpriteAlignment GetSpriteAlignment(GameObject SpriteObject){
		BoxCollider2D MyBoxCollider= SpriteObject.AddComponent<BoxCollider2D> ();
		float colX = MyBoxCollider.center.x;
		float colY = MyBoxCollider.center.y;
		if (colX > 0f && colY < 0f)
			return (SpriteAlignment.TopLeft);
		else if (colX < 0 && colY < 0)
			return (SpriteAlignment.TopRight);
		else if (colX == 0 && colY < 0)
			return (SpriteAlignment.TopCenter);
		else if (colX > 0 && colY == 0)
			return (SpriteAlignment.LeftCenter);
		else if (colX < 0 && colY == 0)
			return (SpriteAlignment.RightCenter);
		else if (colX > 0 && colY > 0)
			return (SpriteAlignment.BottomLeft);
		else if (colX < 0 && colY > 0)
			return (SpriteAlignment.BottomRight);
		else if (colX == 0 && colY > 0)
			return (SpriteAlignment.BottomCenter);
		else if (colX == 0 && colY == 0)
			return (SpriteAlignment.Center);
		else
			return (SpriteAlignment.Custom);
	}
}

Adapted from abeldantas
This exposes public variables that allow you to specify how many tiles you want on a grid, instead of having to modify the original source sprite/texture.

using UnityEngine;
using System.Collections;

// @NOTE the attached sprite's position should be "Top Right" or the children will not align properly
// Strech out the image as you need in the sprite render, the following script will auto-correct it when rendered in the game
[RequireComponent (typeof (SpriteRenderer))]

// Generates a nice set of repeated sprites inside a streched sprite renderer
// @NOTE Vertical only, you can easily expand this to horizontal with a little tweaking
public class RepeatSpriteBoundary : MonoBehaviour {
	public float gridX = 0.0f;
	public float gridY = 0.0f;

	SpriteRenderer sprite;

	void Awake () {
		
		sprite = GetComponent<SpriteRenderer>();
		if(!GetSpriteAlignment(gameObject).Equals(SpriteAlignment.TopRight)){
			Debug.LogError("You forgot change the sprite pivot to Top Right.");
		}
		Vector2 spriteSize_wu = new Vector2(sprite.bounds.size.x / transform.localScale.x, sprite.bounds.size.y / transform.localScale.y);
		Vector3 scale = new Vector3(1.0f, 1.0f, 1.0f);

		if (0.0f != gridX) {
			float width_wu = sprite.bounds.size.x / gridX;
			scale.x = width_wu / spriteSize_wu.x;
			spriteSize_wu.x = width_wu;
		}

		if (0.0f != gridY) {
			float height_wu = sprite.bounds.size.y / gridY;
			scale.y = height_wu / spriteSize_wu.y;
			spriteSize_wu.y = height_wu;
		}

		GameObject childPrefab = new GameObject();
		
		SpriteRenderer childSprite = childPrefab.AddComponent<SpriteRenderer>();
		childPrefab.transform.position = transform.position;
		childSprite.sprite = sprite.sprite;

		GameObject child;
		for (int i = 0, h = (int)Mathf.Round(sprite.bounds.size.y); i*spriteSize_wu.y < h; i++) {
			for (int j = 0, w = (int)Mathf.Round(sprite.bounds.size.x); j*spriteSize_wu.x < w; j++) {
				child = Instantiate(childPrefab) as GameObject;
				child.transform.position = transform.position - (new Vector3(spriteSize_wu.x*j, spriteSize_wu.y*i, 0));
				child.transform.localScale = scale;
				child.transform.parent = transform;
			}
		}
		
		Destroy(childPrefab);
		sprite.enabled = false; // Disable this SpriteRenderer and let the prefab children render themselves
		
	}
}