I’m getting this error in C# while trying to build an importer for a tilemap. It’s supposed to read files formatted like this;
DatMapName!
6|4
SpritePageID:SpriteID:OffsetX:OffsetY|SpritePageID:SpriteID:OffsetX:OffsetY SpritePageID:SpriteID:OffsetX:OffsetY
SpritePageID:SpriteID:OffsetX:OffsetY|SpritePageID:SpriteID:OffsetX:OffsetY SpritePageID:SpriteID:OffsetX:OffsetY
into a data structure built up like this;
map
MapTile[MapSizeX, MapSizeY]
Tile[Sprites on tile]
- string SpritePageID
- int SpriteID
- Vector2 Offset
Basically it has the map name on the first line, X/Y size on the second, and then it has SpritePageID, spriteID, offsetx, offsetY separated by :, and multiple sprites per tile separated by |. Spaces delimit the different tiles.
However, during processing I get the following error;
Error 1 Building content threw NullReferenceException: Object reference not set to an instance of an object.
at LibTilePipelineExtension.LevelProcessor.Process(String input, ContentProcessorContext context) in C:\Projects\C#\XNA1\TileWorld\LibTilePipelineExtension\LevelProcessor.cs:line 45
at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAssetWorker(BuildItem item)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAsset(BuildItem item)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.RunTheBuild()
at Microsoft.Xna.Framework.Content.Pipeline.Tasks.BuildContent.RemoteProxy.RunTheBuild(BuildCoordinatorSettings settings, TimestampCache timestampCache, ITaskItem[] sourceAssets, String[]& outputContent, String[]& rebuiltContent, String[]& intermediates, Dictionary`2& dependencyTimestamps, KeyValuePair`2[]& warnings)
C:\Projects\C#\XNA1\TileWorld\TileWorld\TileWorldContent\tileworldtest1.tilemap TileWorld
Here’s the code that’s throwing this error.
string[] lines = input.Split(new char[] { '\n' });
// ------
// Clear out commented lines from the array. Turn it to a list, remove indices, turn back to array.
List<string> derp1 = new List<string>(lines);
for (int derp2 = 0; derp2 < derp1.Count; derp2++) {
if (derp1[derp2][0] == ' ' || derp1[derp2][0] == ';') {
derp1.RemoveAt(derp2);
derp2--;
}
}
lines = derp1.ToArray();
// ------
int rows = Convert.ToInt32(lines[1].Split('|')[0]);
int columns = Convert.ToInt32(lines[1].Split('|')[1]);
MapTile[,] res = new MapTile[rows, columns];
for (int i0 = 2; i0 < (rows + 2); i0++) {
string[] tiles = lines[i0].Split(' ');
for (int i1 = 0; i1 < columns; i1++) {
string[] tileSprites = tiles[i1].Split('|');
--> res[i0 - 2, i1].sprites = new Tile[tileSprites.Length]; <-- Exception
for (int i2 = 0; i2 < tileSprites.Length; i2++) {
string[] spriteData = tileSprites[i2].Split(':');
res[i0 - 2, i1].sprites[i2] = new Tile(spriteData[0], Convert.ToInt32(spriteData[1]), new Vector2(Convert.ToInt32(spriteData[2]), Convert.ToInt32(spriteData[3])));
}
}
}
return new Map(res, lines[0]);
These are the classes I use to make this tree. I removed the using statements to shorten this question.
//Map.cs
namespace LibTile {
public class Map {
public MapTile[,] grid { get; set; }
public string MapName { get; set; }
public Map(MapTile[,] value) {
grid = value;
}
public Map(MapTile[,] value, string name) {
grid = value;
MapName = name;
}
public MapTile GetTile(int row, int col) {
return grid[row, col];
}
public int Rows {
get {
return grid.GetLength(0);
}
}
public int Columns {
get {
return grid.GetLength(1);
}
}
}
}
.
//MapTile.cs
namespace LibTile {
public class MapTile {
public Tile[] sprites { get; set; }
public MapTile(Tile[] value) {
sprites = value;
}
}
}
.
//Tile.cs
namespace LibTile {
public class Tile {
public String SpritePageID;
public int SpriteID;
public Vector2 Offset;
public Tile(String spid, int sid, int ox, int oy) {
SpritePageID = spid;
SpriteID = sid;
Offset = new Vector2(ox,oy);
}
public Tile(String spid, int sid, Vector2 o) {
SpritePageID = spid;
SpriteID = sid;
Offset = o;
}
}
}
You create a new array of
MapTilebut you never initialize the individual elements. Try this:This will create a new
MapTileobject in each poition of the array. Not doing this was causing your null reference exception. I would also consider changing the constructor ofMapTileto be parameterless and then just setMapTile.spritesas you were doing before.