5
\$\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\$
  • 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 '15 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 '15 at 18:26
  • 1
    \$\begingroup\$ Ha, sorry, my bad I read too fast apparently. I removed my comment :) \$\endgroup\$ – Vaillancourt Sep 3 '15 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\$ – Kyle Humfeld Jul 22 '19 at 22:19
4
\$\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\$
  • \$\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 '15 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 '15 at 18:42
  • \$\begingroup\$ I couldn't find pixel settings : imgur.com/G0LRmQ4 \$\endgroup\$ – Eray Sep 3 '15 at 18:54
  • \$\begingroup\$ just saw your edit. Please look at Update 1 on my question. \$\endgroup\$ – Eray Sep 3 '15 at 19:17
  • \$\begingroup\$ Bingo ! Your last edit solved problem. Thank you so much \$\endgroup\$ – Eray Sep 3 '15 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
    \$\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 '15 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\$
  • \$\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 '15 at 18:19
  • \$\begingroup\$ Edited the answer \$\endgroup\$ – Hash Buoy Sep 3 '15 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 '15 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 '15 at 19:26
  • \$\begingroup\$ but tiling not working as expected. Can you please check UPDATE 1 at question? \$\endgroup\$ – Eray Sep 3 '15 at 19:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.