Hi All
Aplogies if this is more a c# query, but I can’t find any details generally so far.
I have a 2D map that represents legal positions for creatures and players in the world. The world is 3d but movement is tile based. I have a serializable class for each tile and a 1d array I treat as 2d via a GetTile() method. Some of my tiles are not accessible and so I wanted to set the array location to null, but it doesn’t appear to work - when I inspect the array on load, each index contains a tile class, although where the tiles should be null they are only partially constructed?
Any help greatly apprechiated!
[Edit]
Thanks for all the help so far. Here’s the code with the bodies edited out
[System.Serializable]
public class BVMapTile
{ // [EDIT] clearly a tile isn't empty but the contents probably don't tell you much
}
[System.Serializable]
public class BVMap2D : MonoBehaviour
{ // map data
public int MaxX = 0;
public int MaxZ = 0;
public BVMapTile[] Tiles = null; // array is single but treated like 2D
// gets a tile
public BVMapTile GetTile(int x, int z)
{ // return the tile specified
return Tiles[x * MaxZ + z];
}
public void SetTile(int x, int z, BVMapTile tile)
{ // set the tile
Tiles[x * MaxZ + z] = tile;
}
}
[CustomEditor(typeof(BVMap2D))]
public class BVMap2DEditor : Editor
{
static bool m_render_boxes = true;
void OnSceneGUI()
{ // [EDIT] I'm drawing some handles here
}
[DrawGizmo(GizmoType.NotSelected)]
static void RenderLevelHullGizmo(GameObject obj, GizmoType type)
{ // if the selection is same we might care
if(!Selection.Contains(obj)) return;
// [EDIT] I'm drawing some gizmos here, I look for the component type on the GameObject and bail if its not there
}
Vector3 m_move_height = new Vector3(0, 1, 0); // if we collide at this height we cannot pass between squares
Vector3 m_sight_height = new Vector3(0, 1.5f, 0); // if we collide at this height we cannot see between squares
// map of calculated grounds positions
Dictionary<BVMapTile, Vector3> m_calculated_ground_positions = new Dictionary<BVMapTile, Vector3>();
public override void OnInspectorGUI()
{ // get the map
BVMap2D map = target as BVMap2D;
Transform t = map.transform;
// build map button
if(GUILayout.Button("Build Map"))
{ // warning!
// clear map of ground positions
m_calculated_ground_positions.Clear();
// calculate the size of the map, from the handles in the scene
Vector3 size = map.UpperBounds;
size -= map.LowerBounds;
int max_x = (int) ((size.x + 0.2f) / BVMap2DConstants.TileSize);
int max_z = (int) ((size.z + 0.2f) / BVMap2DConstants.TileSize);
// create a new map!
map.Tiles = new BVMapTile[max_x * max_z];
map.MaxX = max_x;
map.MaxZ = max_z;
// [EDIT]
// *** The Relevant Collision Models are parsed to decide whether the tile position is accessible. ***
// the final pass will decides whether the tile is closed
for(int x=0; x<max_x; ++x)
{ // for each z tile
for(int z=0; z<max_z; ++z)
{ // get the tile we are on
BVMapTile tile = map.GetTile(x, z);
tile.DetermineClosed();
// if the tile has an entry, set the ground position
tile.HaveGroundPosition = tile.HaveGroundPosition || m_calculated_ground_positions.TryGetValue(tile, out tile.GroundPosition);
if(!tile.HaveGroundPosition || !tile.TileOpen)
{ // this sets the tile in the array to null
map.SetTile(x,z, null);
}
}
}
}
if(GUI.changed)
EditorUtility.SetDirty(target);
}
}
Apologies if the code is a bit odd looking - I have trouble pasting code into Unity Answers. Hopefully I didn’t edit away too much.
Some points to note:
- I am using a public 1d array to benefit from Unity’s serialisation (2d arrays don’t get serialised)
- It seems I may not want to benefit from Unity’s in built serialisation given answers to date…
- The tiles are serializable classes
- I’m setting the contents of the array in a custom editor which boils collision models within an array defined by two handles down to a 2D grid.
This looks like so in the editor for anyone who might be interested:
I’ll respond to comments below, but it looks like the Unity default serialisation is getting in my way a little - how can I work around this?
Thanks
Ian H