4
\$\begingroup\$

I'm learning Unity by developing a 2D game. It's similar to RimWorld and Prison Architect. I have a 32×32-pixel grass tile image that I want to fill the background with.

Here's a screenshot from Prison Architect to demonstrate what I want:

Prison Architect: empty map

I created a 2D sprite and set the grass image as sprite and created a prefab with this gameobject. I used this to fill background with prefab:

 // This script attached to main camera
for (int q = -1*(Camera.main.pixelHeight/2); q<Camera.main.pixelHeight; q++) {
    for (int i = -1*(Camera.main.pixelWidth/2); i<Camera.main.pixelWidth; i++) {
        Instantiate (grass, new Vector3 ((float)i, (float)q, 0f), Quaternion.identity);
    }
}

It's really slow because it's creating 619200 instances of the prefab for 860×720 screen resolution.

How can I better do this?


UPDATE 1

After Joe's answer.

  1. Imported grass image to Unity

    enter image description here

  2. Created new material

    enter image description here

  3. Created a quad and set grass material

    enter image description here

  4. Result (ignore the purple thing):

    enter image description here

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Seems like op is looking for an alternative to the method used in that question... I've suggested something in my answer but I may be misinterpreting the ask \$\endgroup\$
    – Joe
    Sep 3, 2015 at 18:21
  • \$\begingroup\$ @AlexandreVaillancourt , it's not duplicate, I'm looking for alternative method because that method creating too much instances for my case. \$\endgroup\$
    – Eray
    Sep 3, 2015 at 18:26
  • 1
    \$\begingroup\$ Ha, sorry, my bad I read too fast apparently. I removed my comment :) \$\endgroup\$
    – Vaillancourt
    Sep 3, 2015 at 18:30
  • \$\begingroup\$ Is it just me, or did this not tile your image at all? It's there in the bottom-left corner, and then various smears for the rest of the image. Did you figure out how to actually get it to tile? I'm trying to do something similar in a 2D game I'm making, but I'm having similar (incorrect) results that you show above. \$\endgroup\$ Jul 22, 2019 at 22:19

3 Answers 3

3
\$\begingroup\$

In unity you can create one material that utilizes the texture you want to tile and one "Surface Geometry" either quad or plane. Apply your new material to your new geometry and from there in the inspector, choose the Tiling amount both on the X and Y axes based upon the size of your Texture and the size of the Geometry. (eg if your texture is 16x16 and the floor is 160x160, you will want to tile your texture 10x10)

Material

Take a look at the documentation for working with materials here.

Just like you said your performance is taking a huge hit because of the amount of game objects you are creating, when instead you should just make one GameObject and repeat the image rendered on it

EDIT!: That specific diffuse shader is just an example, you can use almost any shader type that accepts a texture. Even the new unity5 "Standard" shader accepts multiple image textures, but the most basic "Albedo" will allow you to tile it Standard Shader Docs

EDIT2: Forgot to mention texture wrap mode needs to be set from Clamp to Repeat

\$\endgroup\$
5
  • \$\begingroup\$ Hello Joe, I'm trying it now but in Unity 5 there is no Diffuse shader, but Legacy Shaders/Diffuse. I'll use it right? \$\endgroup\$
    – Eray
    Sep 3, 2015 at 18:33
  • \$\begingroup\$ here what i did exactly. 1) Set grass image's texture type: Texture 2) Create a new material with Standard shader, set Albedo as grass texture. 3) Material's tiling x=10 and y=10 4) Created a quad with 100x100 scale. Set quad's mesh renderer material as grass material. But result : imgur.com/04ZWoWU (nevermind that purple thing) \$\endgroup\$
    – Eray
    Sep 3, 2015 at 18:42
  • \$\begingroup\$ I couldn't find pixel settings : imgur.com/G0LRmQ4 \$\endgroup\$
    – Eray
    Sep 3, 2015 at 18:54
  • \$\begingroup\$ just saw your edit. Please look at Update 1 on my question. \$\endgroup\$
    – Eray
    Sep 3, 2015 at 19:17
  • \$\begingroup\$ Bingo ! Your last edit solved problem. Thank you so much \$\endgroup\$
    – Eray
    Sep 3, 2015 at 19:32
3
\$\begingroup\$

Instead of a separate object for each tile, your map should be a single object that's a grid of polygons and the UVs for each square are set to different images.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thank you for response. But it's a little complicated for me. Actually I couldn't understand anything :) Can you please provide some tutorials or at least keywords so I can google them. \$\endgroup\$
    – Eray
    Sep 3, 2015 at 18:05
0
\$\begingroup\$

Hey I have answered a similar question before , here is the link -

https://gamedev.stackexchange.com/a/105947/40457

It basically fills out the screen using a tile map , which is nothing but a 2D array. If you find it difficult to implement then try out some plugins on the asset store to get started :)

Ok so the lag is basically due to the instantiating of gameobjects , which can be avoided. Make a parent in the game scene and add all tiles as children, ON awake just call Get Children function to reference those tiles into an array. Now replace the instantiate code with iteration over the tile pool array and use the tile which is idle or disabled.

As per the reference image you have provided , it looks more like unity terrain , may be you want to explore that option also :)

\$\endgroup\$
6
  • \$\begingroup\$ Thank you for link. But it's doing almost same thing with me. In your question, you are creating a 3x3 map. But in my case I need a bigger map. So I need to use 26x22 map (world size 860x720 and every tile 32*32) and it will create 572 instances from prefab. \$\endgroup\$
    – Eray
    Sep 3, 2015 at 18:19
  • \$\begingroup\$ Edited the answer \$\endgroup\$
    – Hash Buoy
    Sep 3, 2015 at 18:34
  • \$\begingroup\$ Already tried to make all tile objects child of a gameobject like you said. But it's still laggy because it's creating too much object doesn't matter if they are children of an object or not. \$\endgroup\$
    – Eray
    Sep 3, 2015 at 18:56
  • \$\begingroup\$ In that case Joe's solution is better, here is a screen shot on how to get the material setup in the editor. I have used normal unity plane - i.stack.imgur.com/kFGhD.png \$\endgroup\$
    – Hash Buoy
    Sep 3, 2015 at 19:26
  • \$\begingroup\$ but tiling not working as expected. Can you please check UPDATE 1 at question? \$\endgroup\$
    – Eray
    Sep 3, 2015 at 19:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .