Search Unity

Faster pixel modification at runtime

Discussion in '2D' started by Fermak, Nov 19, 2018.

  1. Fermak

    Fermak

    Joined:
    Sep 6, 2017
    Posts:
    4
    Hello, I have been working on a procedurally generated 2d map program using perlin noise. I have the project working, using minecraft as a sort of starting point for how to think about things. I have been able to generate chunks of 10x10 tiles and put them together into a single texture, then have a map that takes all those textures and displays them as a single... However it is slow as can be.
    Code (CSharp):
    1.  private Sprite BuildMapSprite()
    2.     {
    3.         //create a texture a number of pixels large as the number of chunks to show
    4.         Texture2D texture = new Texture2D(Chunk.CHUNK_WIDTH * Chunk.BLOCK_WIDTH * MAP_WIDTH, Chunk.CHUNK_HEIGHT * Chunk.BLOCK_HEIGHT * MAP_HEIGHT);
    5.         for (int x = 0; x < MAP_WIDTH; ++x)
    6.         {
    7.             for(int y = 0; y < MAP_HEIGHT; ++y)
    8.             {
    9.                 //get the block (x) in the chunk ((int)Camera.main.transform.position / 4)
    10.                 Color[] chunkPixels = getChunkByPos(x + (int)Camera.main.transform.position.x / 4, y + (int)Camera.main.transform.position.y / 4).ChunkMesh.GetPixels();
    11.                 texture.SetPixels(x * Chunk.CHUNK_WIDTH * Chunk.BLOCK_WIDTH,
    12.                     y * Chunk.CHUNK_HEIGHT * Chunk.BLOCK_HEIGHT,
    13.                     Chunk.CHUNK_WIDTH * Chunk.BLOCK_WIDTH,
    14.                     Chunk.CHUNK_HEIGHT * Chunk.BLOCK_HEIGHT,
    15.                     chunkPixels);
    16.             }
    17.         }
    18.         texture.Apply();
    19.      
    20.         Rect rect = new Rect(0, 0, texture.width, texture.height);
    21.  
    22.         return Sprite.Create(texture, rect, new Vector2(.5f,.5f));
    23.     }
    The above code works, but getting all the pixels from each chunk that I want to show and then putting those pixels on the map texture is chugging the game every time I call the method. Is there any better way of putting all the chunk textures together rather than pixel by pixel?
     
  2. qqqbbb

    qqqbbb

    Joined:
    Jan 13, 2016
    Posts:
    113
    Cache Camera.main. It uses Gameobject.Find.

    Why don't you use tilemaps? It will be faster than any custom system.
     
  3. Fermak

    Fermak

    Joined:
    Sep 6, 2017
    Posts:
    4
    Right, the camera should be a fairly minor stress in all of this, though.
    I'm not using tilemaps because the map is going to be editable by tile, I didn't think tilemaps were good for that, though I might be wrong.
     
    Last edited: Nov 19, 2018
  4. Fermak

    Fermak

    Joined:
    Sep 6, 2017
    Posts:
    4
    So I have discovered part of my issue is that creating a sprite with a texture that big is really slow. It is accounting for nearly half my frame rate drop. Is there a better way to change a texture at runtime?
     
  5. mvinc006

    mvinc006

    Joined:
    Jan 1, 2018
    Posts:
    91
    Tilemaps is definitely much better to achieve what you’re after.

    Currently I’m building a dwarf fortress/rimworld type game and this is what I’m using.

    • To switch a given tile (I.e dirt to stone) in a tilemap you simply apply a new TIle (which has a sprite/sprite animation attached). This is very easily done via code and I can show examples. It’s literally as simple as
      Code (csharp):
      1. setTile
    • Tilemaps and tiles can use physics just like any other regular sprite that you drop into the scene.
    • Much more efficient rendering, you can get things down to a few batches quite easily.
    Also you’ll want to cache your camera as already suggested, your calling gameobject.find literally tens of thousands of times in your for loop.
     
    Last edited: Nov 20, 2018
  6. Fermak

    Fermak

    Joined:
    Sep 6, 2017
    Posts:
    4
    Thanks a bunch, I have been looking more into tilemaps and I can see how I misunderstood them before. I have been working on cashing more and more stuff and I have gotten up to 90fps using tilemaps rendering more than 10,000 tiles.
     
  7. mvinc006

    mvinc006

    Joined:
    Jan 1, 2018
    Posts:
    91
    Awesome have fun