Hi.
I am attempting to generate a grid and storing the individual Tiles in a 2 dimensional array. But as soon as I am attempting to access the the tiles in the array I get a “null reference exception” Bellow I have included some of the code, if someone could tell me what I’m doing wrong.
Strip down grid generation script:
public class Grid : MonoBehaviour
{
public Tile[,] Map;
public int gridWidthInHexes = 10;
public int gridHeightInHexes = 10;
private void createGrid()
{
int tempTileIndex = 0;
int curMapIndexHeight = 0;
for (float y = 0; y < gridHeightInHexes; y++)
{
int curMapIndexWidth = 0;
for (float x = 0; x < gridWidthInHexes; x++)
{
var hex = (GameObject) Instantiate(Hex);
var gridPos = new Vector2(x, y);
var tempTile = hex.GetComponent<Tile>();
tempTile.TileIndex = tempTileIndex;
Map[curMapIndexWidth, curMapIndexHeight] = hex.GetComponent<Tile>();
tempTileIndex++;
curMapIndexWidth++;
}
curMapIndexHeight++;
}
}
private void Start()
{
Map = new Tile[gridWidthInHexes,gridHeightInHexes];
createGrid();
}
}
Strip down game manager script:
public partial class GameMaster : MonoBehaviour
{
private Grid grid;
public GameObject unit;
void Start()
{
grid = gameObject.GetComponent<Grid>();
}
void OnMapLoaded()
{
Debug.Log(grid.Map[1, 3].TileIndex);
}
}
The Tile script is not that interesting. It only contains some variables.
Please help.
The Error massage is: NullReferenceException: Object reference not set to an instance of an object
GameMaster.OnMapLoaded () (at Assets/_Scripts/GameMaster.cs:19)
GameMaster._LoadedMap () (at Assets/_Scripts/GameEvents.cs:15)
Grid.Start () (at Assets/_Scripts/Grid.cs:99)
Here are the entire scripts: Grid (should be attached to _GameMaster):
using System.Collections.Generic;
using UnityEngine;
public class Grid : MonoBehaviour
{
private GameMaster gameMaster;
//The Map
public Tile[,] Map;
//following public variable is used to store the hex model prefab;
public GameObject Hex;
//next two variables can also be instantiated using unity editor
public int gridWidthInHexes = 10;
public int gridHeightInHexes = 10;
//Hexagon tile width and height in game world
private float hexWidth;
private float hexHeight;
//Method to initialise Hexagon width and height
private void setSizes()
{
//renderer component attached to the Hex prefab is used to get the current width and height
hexWidth = Hex.renderer.bounds.size.x;
hexHeight = Hex.renderer.bounds.size.z;
}
//Method to calculate the position of the first hexagon tile
//The center of the hex grid is (0,0,0)
private Vector3 calcInitPos()
{
Vector3 initPos;
//the initial position will be in the left upper corner
initPos = new Vector3(-hexWidth*gridWidthInHexes/2f + hexWidth/2, 0,
gridHeightInHexes/2f*hexHeight - hexHeight/2);
return initPos;
}
//method used to convert hex grid coordinates to game world coordinates
public Vector3 calcWorldCoord(Vector2 gridPos)
{
//Position of the first hex tile
Vector3 initPos = calcInitPos();
//Every second row is offset by half of the tile width
float offset = 0;
if (gridPos.y%2 != 0)
offset = hexWidth/2;
float x = initPos.x + offset + gridPos.x*hexWidth;
//Every new line is offset in z direction by 3/4 of the hexagon height
float z = initPos.z - gridPos.y*hexHeight*0.75f;
return new Vector3(x, 0, z);
}
//Finally the method which initialises and positions all the tiles
private void createGrid()
{
Map = new Tile[gridWidthInHexes, gridHeightInHexes];
//Game object which is the parent of all the hex tiles
var hexGridGO = new GameObject("HexGrid");
int tempTileIndex = 0;
int curMapIndexHeight = 0;
for (float y = 0; y < gridHeightInHexes; y++)
{
int curMapIndexWidth = 0;
for (float x = 0; x < gridWidthInHexes; x++)
{
//GameObject assigned to Hex public variable is cloned
var hex = (GameObject) Instantiate(Hex);
//Current position in grid
var gridPos = new Vector2(x, y);
var tempTile = hex.GetComponent<Tile>();
tempTile.TilePos = gridPos;
tempTile.TileIndex = tempTileIndex;
hex.transform.position = calcWorldCoord(gridPos);
hex.transform.parent = hexGridGO.transform;
Map[curMapIndexWidth, curMapIndexHeight] = hex.GetComponent<Tile>();
tempTileIndex++;
curMapIndexWidth++;
}
curMapIndexHeight++;
}
}
//The grid should be generated on game start
private void Start()
{
gameMaster = gameObject.GetComponent<GameMaster>();
setSizes();
createGrid();
if (gameMaster != null)
{
gameMaster._LoadedMap();
}
}
}
One of the GameMaster scripts should be attached to _GameMaster :
using UnityEngine;
public partial class GameMaster : MonoBehaviour
{
private Grid grid;
public GameObject unit;
void Awake()
{
MapLoaded += OnMapLoaded;
}
void Start()
{
grid = gameObject.GetComponent<Grid>();
}
void OnMapLoaded()
{
Debug.Log("Generated Map");
Debug.Log(grid.Map[1, 3].TileIndex);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (MouseClick != null)
MouseClick(0);
}
if (Input.GetMouseButtonDown(1))
{
if (MouseClick != null)
MouseClick(1);
}
if (Input.GetMouseButtonDown(2))
{
if (MouseClick != null)
MouseClick(2);
}
}
}
public partial class GameMaster
{
public delegate void LoadingDeligate();
public event LoadingDeligate MapLoaded;
public delegate void ClickEvents(int button);
public event ClickEvents MouseClick;
public void _LoadedMap()
{
if (MapLoaded != null)
MapLoaded();
}
}
The tile script is attached to the tile Prefab:
using UnityEngine;
public class Tile : MonoBehaviour
{
private int _tileIndex;
private Vector2 _tilePos;
private GameObject _unit;
private bool isHoverd;
private GameObject GMObject;
private GameMaster gameMaster;
private bool isSelected;
public Texture defultTexture;
public Texture hoverTexture;
public Texture selectedTexture;
public int TileIndex
{
get { return _tileIndex; }
set { _tileIndex = value; }
}
public Vector2 TilePos
{
get { return _tilePos; }
set
{
_tilePos = value;
Debug.Log("New TilePos: " + _tilePos);
}
}
public GameObject Unit
{
get { return _unit; }
set { _unit = value; }
}
void Start ()
{
GMObject = GameObject.FindGameObjectsWithTag("GameController")[0];
gameMaster = GMObject.GetComponent<GameMaster>();
gameMaster.MouseClick += OnButtonPress;
}
void OnButtonPress(int button)
{
if (isHoverd && button == 0)
{
renderer.material.SetTexture("_MainTex", selectedTexture);
isSelected = true;
}
else if (!isHoverd && button == 0 && !Input.GetKey(KeyCode.LeftShift))
{
renderer.material.SetTexture("_MainTex", defultTexture);
isSelected = false;
}
}
void OnMouseEnter()
{
if (!isSelected)
{
renderer.material.SetTexture("_MainTex", hoverTexture);
}
isHoverd = true;
Debug.Log("hovering: " + _tileIndex);
}
void OnMouseExit()
{
if (!isSelected)
{
renderer.material.SetTexture("_MainTex", defultTexture);
}
isHoverd = false;
}
}
Everything works with the exception of accessing the map array and the only error I get is when I’m trying to access the array with the map stored in.