Grid based Map, store Tiles in Array

I try to script the placement of 3d Tiles on a Grid,

what ist working:

  • Getting the right target via raycast from camera to mouseposition
  • Spawning Tiles(Gameobjects) at the target
  • Filling up the array acordingly with the same Gameobject at the right position.

but what isn’t working

  • I do it basicaly 2 ways, spawning a tile putting a tile in the array
    they have nothing to do with each other.
  • I need store the info in the array and create the tiles from the array

I read lots of stuff but did not progress on this problem, if anyone knows, thanks a lot for explaining

the script so far:

  • first part is the raycast getting th target
  • second creating objects by mouseclick
  • last is instanciating the object on the build-grid
using UnityEngine;
using System.Collections;

public class VirusSpawner: MonoBehaviour
{
	public int x;
	public int y;
	public Vector3 target;
	
	GameObject[,] myArray = new GameObject[10,10];
	
	public GameObject cursor;    // debug cursor
	public GameObject good;	  // tile one, placed with mouse left-btn
	public GameObject bad;       // tile one, placed with mouse left-btn

			
		
	void Update () 
	{
		RaycastHit hit;
	 
		if (Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hit))
		{
			target.x = Mathf.Round(hit.point.x + hit.normal.x * 0.5f ) ;	// die Position über:
			target.y = Mathf.Round(hit.point.y + hit.normal.y * 0.5f ) ;	// von Camera durch Zeigerposition
			target.z = Mathf.Round(hit.point.z + hit.normal.z * 0.5f ) ;	// und wird aufgerundet
			
			x = (int)target.x;
			y = (int)target.z;
			
			
			if (hit.collider.name == "BuildGround"  Input.GetMouseButtonDown(0))
			{
				//myArray[x, y] = good;
				CreateTile (x, y, good);
			}
			
			if (hit.collider.name == "BuildGround"  Input.GetMouseButtonDown(1))
			{
				myArray[x, y] = bad;
				CreateTile (x, y, bad);
			}
		}
		
			
		cursor.transform.position = target;	//debug cursor position	
	}
	
	
	private GameObject CreateTile (int i, int j, GameObject tile)		
	{																	
		//decalPrefab = good;								
		GameObject go = (GameObject)Instantiate(tile, new Vector3(i , 0.5F, j), Quaternion.identity);
		Tile t = go.AddComponent<Tile>();
		t.x = i;
		t.y = j;
		return go;
	}
	
}

It’s meant to be like a board game where you can place Stuff:

For something like this the following question is important:

How big is the maximum map going to be (X,Y)?
What are the weakest machines is it going to run on?

you need to elaborate on

at least I don’t get it.
Looking at your code, you are not referencing the tiles correctly in the array. You should do:

myArray[x, y] = CreateTile (x, y, bad);

if you have a 2 dimensional int array that stores codes for the tiles, then you would instantiate them, for example

for (i = 0; i < myArray.GetLength(0); i++)
{
      for (j = 0; j < myArray.GetLength(1); j++)
      {
           myTiles[i,j] =  Instantiate(tiles[myArray[i,j]], Vector3(i,0.5,j),Quaternion.identity);
      }
}

where tiles is an array of gameObjects that contains the different types of tiles you would need.

@ivkoni yes you are right i dit it seperately, thanks for the explanation

another frind from ratking.de took a look in the script and now, if someone is interested in the working result:

using UnityEngine;
using System.Collections;

public class VirusSpawner: MonoBehaviour
{
	public int x;
	public int y;
	public Vector3 target;
	
	GameObject[,] myArray = new GameObject[10,10];
	
	public GameObject cursor;
	public GameObject good;	
	public GameObject bad;

	public GameObject showit;	// für debug um array inhalte anzuzeigen
	
		
	void Update () 
	{
		RaycastHit hit;
	 
		if (Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hit))
		{
			target.x = Mathf.Round(hit.point.x + hit.normal.x * 0.5f ) ;	// die Position über:
			target.y = Mathf.Round(hit.point.y + hit.normal.y * 0.5f ) ;	// von Camera durch Zeigerposition
			target.z = Mathf.Round(hit.point.z + hit.normal.z * 0.5f ) ;	// und wird aufgerundet
			
			x = (int)target.x;
			y = (int)target.z;
			
			
			if (hit.collider.name == "BuildGround"  Input.GetMouseButtonDown(0))
			{
				Destroy(myArray[x, y]);		//das löscht das alte tile
				myArray[x, y] = CreateTile (x, y, good);
			}
			
			if (hit.collider.name == "BuildGround"  Input.GetMouseButtonDown(1))
			{
				Destroy(myArray[x, y]);
				myArray[x, y] = CreateTile (x, y, bad);
			}
			
			if (hit.collider.name == "BuildGround"  Input.GetMouseButtonDown(2))
			{
				Destroy(myArray[x, y]);
				myArray[x, y] = null;		// auf null setzen, sonst ist das missing 
			}
		}
		
		
		cursor.transform.position = target;		// die cursor Ziel-Vorschau
		
		showit = myArray[x,y];	// debug, verbessern das wird die ganze zeit berechnet
	}
	
	
		
	//warum ist diese Funktion ein gameobject ?  den Teil hab ich von Dir
	
	private GameObject CreateTile (int i, int j, GameObject tile)		// und demensprechend werden Tiles 0-11 gespawnt 
	{																	//fals hier schon ein Teil ist muß es vorher gelöscht werden
		//decalPrefab = good;								
		GameObject go = (GameObject)Instantiate(tile, new Vector3(i , 0.5F, j), Quaternion.identity);
		Tile t = go.AddComponent<Tile>();		//wohin wird das als Componente hinzugefügt
		t.x = i;
		t.y = j;
		return go;
	}
	
}

Now you can place 2 difrerent objects with the LMB and RMB. They get stored in the array :razz:
Erase them with MMB

Comes up with another problem:

every Object with is instatiated gets a “…(Clone)” atached to it’s name
which makes it hard to refer to it.

Is there a command to instatiate with the name unchanged ?

No, but you can name it whatever you want after you instantiate it.

–Eric

Yes but the name doesn’t seem to have much to do with the variable inside the array of Gameobject

I have 2 variables both Gameobjects: good bad the get stored in the array and now get instatiated in the scene.

I can retrieve whaat is in side the array at the position, but i can’t check for it:

print (myArray[x, y]); 
if ((myArray[x, y])== good)	print ("yes");
else print ("no");

that doesn’t work, if it is over a “good” tile it prints out: good
but the chekup prints no

i gues i have to check for gameobject.name or something

OK the goal is to fin the “bad” tiles
I came across something that works but may be not optimal because

first i check for tiles that are not empty (null)
second i check the name

for (int j = 0; j < 10; j++)
				{
					for (int i = 0; i < 10; i++)
					{
						if(myArray[i, j] != null)
						{
							if((myArray[i, j]).name != "good")
							print ( (myArray[i, j]).name + " at: X" + i +" Y"+j);
						}
					}
				}
			}