Search Unity

Creating a tilemap from using a script

Discussion in 'Scripting' started by Pixitales, Apr 29, 2019.

  1. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    I am trying to create a tile map by using a script. I know there are different other methods to do it but its for learning purposes. It would really be cool if it works, so I can put it in my guitar hero game or rpg.

    The script created my tilemap too big. It spawned extra tiles, which made my tile map too big. If I put one different tile on the tile map, it made like 6 extra of that tile. My tile map layer is 128x128 px and the script made it like 10x times as big. My default tiles are 32x32px.


    This script basically reads the color per unit of your map layer png file. It spawns a tile based on the color to whatever you input it.

    I recommend you to save your project before trying this out though. It might break unity if you mistype something.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5.  
    6. public class LevelManager : MonoBehaviour
    7. {
    8.     [SerializeField]
    9.     private Transform map;
    10.  
    11.     [SerializeField]
    12.     private Texture2D[] mapData;
    13.  
    14.     [SerializeField]
    15.     private MapElement[] mapElements;
    16.  
    17.     [SerializeField]
    18.     private Sprite defaultTile;
    19.  
    20.  
    21.     private Vector3 WorldStartPos
    22.     {
    23.         get
    24.         {
    25.             return Camera.main.ScreenToWorldPoint(new Vector3(0, 0));
    26.         }
    27.     }
    28.  
    29.     // Start is called before the first frame update
    30.     void Start()
    31.     {
    32.         GenerateMap();
    33.     }
    34.  
    35.     private void GenerateMap()
    36.     {
    37.         int height = mapData[0].height;
    38.         int width = mapData[0].width;
    39.  
    40.         for (int i = 0; i < mapData.Length; i++)
    41.         {
    42.             for (int x = 0; x < mapData[i].width; x++)
    43.             {
    44.                 for (int y = 0; y < mapData[i].height; y++)
    45.                 {
    46.                     Color c = mapData[i].GetPixel(x, y); //Gets the color of the current pixel
    47.  
    48.                     MapElement newElement = Array.Find(mapElements, e => e.MyColor == c);
    49.  
    50.                     if (newElement != null)
    51.                     {
    52.                         float xPos = WorldStartPos.x + (defaultTile.bounds.size.x * x);
    53.                         float yPos = WorldStartPos.y + (defaultTile.bounds.size.y * y);
    54.  
    55.                         GameObject go = Instantiate(newElement.MyElementPrefab);
    56.                         go.transform.position = new Vector2(xPos, yPos);
    57.  
    58.                         if (newElement.MyTileTag == "Tree")
    59.                         {
    60.                             go.GetComponent<SpriteRenderer>().sortingOrder = height*2 - y*2;
    61.                         }
    62.                         go.transform.parent = map;
    63.                     }
    64.                 }
    65.             }
    66.         }
    67.     }
    68. }
    69.  
    70. [Serializable]
    71. public class MapElement
    72. {
    73.     [SerializeField]
    74.     private string tileTag;
    75.  
    76.     [SerializeField]
    77.     private Color color;
    78.  
    79.     [SerializeField]
    80.     private GameObject elementPrefab;
    81.  
    82.     public GameObject MyElementPrefab
    83.     {
    84.         get
    85.         {
    86.             return elementPrefab;
    87.         }
    88.     }
    89.  
    90.     public Color MyColor
    91.     {
    92.         get
    93.         {
    94.             return color;
    95.         }
    96.     }
    97.  
    98.     public string MyTileTag
    99.     {
    100.         get
    101.         {
    102.             return tileTag;
    103.         }
    104.     }
    105. }
    106.  
     
    Last edited: Apr 29, 2019
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Since we don't know what's in your mapData texture array, this is going to be difficult for us to debug. But from afar, I'm a bit surprised that you are trying to set up a time map (which uses x and y for coords) while iterating over three (not two) loops. I don't understand why you are Looping through i -- do you have multiple textures defining the same map? I see that i is giving you the limits for the x and y coords for the individual runs, but they should be set to height and width which you set up before you run the Loops - that's probably explains why your final tile count is off by so much.

    Can you explain in your own words what your loops should be doing, eg if you wrote:

    Code (CSharp):
    1. for every column x from Zero to my map's height i do the following {
    2.   for every row y from Zero to my map 's width I do the followin {
    3.         I set the field (x,y) to Zero
    4.     }
    5. }
    We could quickly Point out that you mixed up height and width.

    So if you tell us what you want and what i, x, and y are doing, and what mapData is, we'd probably get this resolved quickly.

    my best guess is that the order of your Loops is wrong. You probably want to do domething like this:

    Code (CSharp):
    1. for all x from 0 to width-1
    2.   for all y from 0 to height - 1
    3.     create map element for (x,y)
    4.     go through all textures from 0 to i-1 and process Pixel (x,y) of each texture and modify map element (x,y) accordingly
    Cheers,
    -ch