Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How to Implement the Don't Starve like tile style?

Discussion in '2D' started by fpegod, Mar 7, 2019.

  1. fpegod

    fpegod

    Joined:
    Nov 23, 2017
    Posts:
    23
    Anyone know how to implement Don't Starve like tile? It should be made out of 2 kinds of tile texture.

    1. For the tile's edge effect and form its shape
    upload_2019-3-7_15-50-13.png
    2. To fill its inside details.

    They blend those 2 textures somehow, and present this kind of hand draw style which is really cool:

    upload_2019-3-7_15-52-30.png

    I tried to use the shape tile as main texture and set the detail texture as material to every tile, and wrote a simple shader to blend those two. It won't work somehow. What's more, the cost is increased even if I just copy and paste the same tile,, the batches will go up with the tiles I paste.

    Anyone knows how Don't starve did this? Just some direction would be great. Are they using mesh? Or shader?
     
  2. fpegod

    fpegod

    Joined:
    Nov 23, 2017
    Posts:
    23
    upload_2019-3-7_16-14-48.png

    All the tiles are the same object copies. The Batches are as many as the tiles.
     
    Last edited: Mar 7, 2019
  3. fpegod

    fpegod

    Joined:
    Nov 23, 2017
    Posts:
    23
    OK,I just found what happened. I tried to access the material in script. I even just refer it didn't modify anything, it will cause a new batch. I need to think about this a little bit.

    Here is all the code related to material.

    Code (CSharp):
    1.     void Start () {
    2.         rend = GetComponent<Renderer>();
    3.         spriteRender = GetComponent<SpriteRenderer>();
    4.         material = rend.material;
    5.         boarder = Resources.LoadAll<Sprite>("Sprites/bianyuan");
    6.         baseTexture = Resources.LoadAll<Sprite>("Sprites/wenli");
    7.  
    8.     }
    Ok, this is not really the problem is. Anyone know how Don't starve implement this? Thank you all~
     
    Last edited: Mar 7, 2019
  4. fpegod

    fpegod

    Joined:
    Nov 23, 2017
    Posts:
    23
    I got another idea today.

    Us mesh to render the tiles. Mesh can hold multiple UV sets. With those set I can refer to certain part of my texture even if those textures are in one texture atlas. I can access and set those UV sets via script in runtime. Seems doable for me. I will try to implement it tomorrow.
     
  5. beanie4now

    beanie4now

    Joined:
    Apr 22, 2018
    Posts:
    311
    Could you just use a Sprite Mask that uses the tile data as the mask and then masks a tilemap full of the texture?
     
  6. fpegod

    fpegod

    Joined:
    Nov 23, 2017
    Posts:
    23
    I did a little test before, every mask will get you a new drawcall somehow. May be there is something I misunderstand.

    For now, I think mesh would be a good way. Will try it recently.
     
  7. AndreasScholl

    AndreasScholl

    Joined:
    Oct 16, 2015
    Posts:
    12
    I am thinking about this lately as i am planning to use a similar aproach.

    In general i would say you would use a tilemesh that you setup yourself where each quad composed of two triangles represents one tile.

    Next part is rendering of the tiles. To render a tile you will need in you example two textures:
    1. ground (lower texture) with different ground tiles
    2 mask (upper texture) with different upper tiles (including a alpha channel for masking)

    In the tile mesh you can use two UV-sets.
    UV-set 1 will reference the background tiles
    UV-set 2 will reference the upper mask tiles

    The shader of the tilemap whould read those two textures regarding to the uv-coordinates of each uv-set and calculate the pixel. Either by just deciding which texture to use (like a cutout effect) or blend them together if you have a mask (upper texture) with alpha values other than 1 or 0.

    A more genereic approach could be to use 3 textures / 3 uv-sets.
    1. lower tiles
    2. mask tile (gerneric)
    3. upper tiles

    For generating the tilemap data you should have a tile-map editor that allows you to draw tiles in two layers. I think for the level-designer it would be nice to have a editor where you can just drawn with different ground materials and the editor will generate the appropiate mask data. I remember this from the warcraft-2 map editor.
     
  8. unity_i8A2Ar0E9oQOLA

    unity_i8A2Ar0E9oQOLA

    Joined:
    Aug 6, 2018
    Posts:
    1
    Probably late, but for anyone else interested in such tiling technique, I'd like to share how I achieve the effect. There is no need to use complicated meshes (at least complicated for me).

    I created a Tilemap to draw and manage tiles, and wrote a shader that simply blends tiles with the "noise" texture by multiplying their RGBA values.
    Here are some essential parts of my shader:
    Code (CSharp):
    1. float2 noiseUV = float2(0, 0);
    2. noiseUV.x = (i.vertex.x % _Width / _Width + 1) % 1;
    3. noiseUV.y = (i.vertex.y % _Height / _Height + 1) % 1;
    4.  
    5. half4 main = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv) * SAMPLE_TEXTURE2D(_NoiseTex, sampler_NoiseTex, noiseUV);
    _MainTex is set automatically by TilemapRenderer (different depending on tiles), so we only need to assign the _NoiseTex, either in editor or script.
    _Width and _Height are the size of the noise texture relative to world space, also assigned externally.
    NoiseUV is the normalized position in the noise texture. It is calculated according to the object's origin (i.vertex) in world space, so that the ground looks continuous even though they are drawn with separate tiles.

    This is how the noise texture looks like: Ground_noise_grass_detail.png

    This is how the final tilemap looks like:
    upload_2020-7-7_2-16-6.png

    If anyone wants the entire shader file, just tell me to post it. I wrote it based on LWRP sprite-lit-default shader, which it is pretty long and contains much irrelevant stuff.
     

    Attached Files:

    ronJohnJr and Kukiss718 like this.
  9. axaxi

    axaxi

    Joined:
    Jul 7, 2020
    Posts:
    5
    thanks for helping !