Hello everyone,
Solved
Oh lawdy. This was a silly mistake.
In my Writer class I had written such a method:
public override string GetRuntimeReader(TargetPlatform targetPlatform)
{
return "shmup_monogame.TexturePackerXmlReader, shmup_monogame";
}
which was almost correct. My project was called shmup-monogame, so the correct version is
return "shmup_monogame.TexturePackerXmlReader, shmup-monogame";
I guess the takeaway is, don’t name projects with hyphens.
Original Question
this one has stumped me a little. I followed the Creating custom content importers for the MonoGame Pipeline tutorial to make my own XML format for TextureAtlases. My problem is that MGCB works- it builds my XML and I have double and triple-checked my references. Both projects run with .Net Framework 4.5 (the content pipeline project started with 4.0)
As soon as I try to load my game it crashes with the error Could not load art\uiAtlas asset as a non-content file!
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
_spriteBatch = new SpriteBatch(GraphicsDevice);
uiAtlas = Content.Load<TextureAtlas>("art/uiAtlas");
}
I have tried different permutations:
- putting the file in the base Content directory
- referencing it fully (“art/uiAtlas.xml”)
- removing and adding my .dll reference
- clean rebuilds of my pipeline extension project
- removing and adding my .xml
Writer:
[ContentTypeWriter]
public class TexturePackerXmlWriter : ContentTypeWriter<TextureAtlas>
{
protected override void Write(ContentWriter output, TextureAtlas value)
{
output.Write(value.SourceFile);
output.Write(value.Width);
output.Write(value.Height);
output.Write(value.TextureRegions.Count);
foreach (var region in value.TextureRegions)
{
output.Write(region.Name);
output.Write(region.Width);
output.Write(region.Height);
output.Write(region.X);
output.Write(region.Y);
output.Write(region.PivotX);
output.Write(region.PivotY);
}
}
public override string GetRuntimeType(TargetPlatform targetPlatform)
{
return typeof(TextureAtlas).AssemblyQualifiedName;
}
public override string GetRuntimeReader(TargetPlatform targetPlatform)
{
return "shmup_monogame.TexturePackerXmlReader, shmup_monogame";
}
}
Reader:
public class TexturePackerXmlReader : ContentTypeReader<TextureAtlas>
{
protected override TextureAtlas Read(ContentReader reader, TextureAtlas existingInstance)
{
var sourceFile = reader.ReadString();
var sourceTexture = reader.ContentManager.Load<Texture2D>(reader.GetRelativeAssetPath(sourceFile));
var sourceWidth = reader.ReadInt32();
var sourceHeight = reader.ReadInt32();
var regionsCount = reader.ReadInt32();
var regions = new List<TextureRegion>();
for (var i = 0; i < regionsCount; ++i)
{
var name = reader.ReadString();
var width = reader.ReadInt32();
var height = reader.ReadInt32();
var x = reader.ReadInt32();
var y = reader.ReadInt32();
var pivotX = reader.ReadDouble();
var pivotY = reader.ReadDouble();
regions.Add(new TextureRegion(name, width, height, x, y, pivotX, pivotY));
}
return new TextureAtlas(sourceTexture, sourceWidth, sourceHeight, regions);
}
}
TextureAtlas:
public class TextureAtlas
{
private readonly Texture2D _source;
public Texture2D Source => _source;
private readonly int _width;
public int Width => _width;
private readonly int _height;
public int Height => _height;
private readonly List<TextureRegion> _regions;
public List<TextureRegion> TextureRegions => _regions;
public TextureAtlas(Texture2D source, int width, int height, List<TextureRegion> regions)
{
_source = source;
_width = width;
_height = height;
_regions = regions;
}
}