I'm attempting to get my head around the XNA content pipeline, and how I can use it to simplify my game code. Specifically, I want to define sprites, sprite sheets, and animations as assets and have them automatically available to me in game code.
At the end of the day, this is what I want to be able to do:
- add a new file with .sprite extension to my content project
- call
contentManager.Load<Sprite>("NameOfSprite");
and get back aSprite
instance
My Sprite
class looks like this:
public class Sprite
{
public Texture2D Texture
{
get { ... }
}
public Rectangle? SourceRectangle
{
get { ... }
}
public Vector2 Origin
{
get { ... }
}
}
The purpose of the Origin
property is not important - it's specific to my game. The point is, I want it to be "packaged up" alongside the texture information.
I've defined a SpriteData
class as:
public sealed class SpriteData
{
public string TextureFilename
{
get;
set;
}
public Rectangle? SourceRectangle
{
get;
set;
}
public Vector2 Origin
{
get;
set;
}
}
And I've added a test.sprite file to my content project as:
<?xml version="1.0" encoding="utf-8" ?>
<XnaContent xmlns:data="MyNamespace">
<Asset Type="data:SpriteData">
<TextureFilename>Sprites\Test.jpg</TextureFilename>
<SourceRectangle>0 5 20 25</SourceRectangle>
<Origin>30 2</Origin>
</Asset>
</XnaContent>
I have defined a SpriteImporter
as:
[ContentImporter(".sprite", DisplayName = "Sprite Importer", DefaultProcessor = "SpriteProcessor")]
public class SpriteImporter : ContentImporter<SpriteData>
{
public override SpriteData Import(string filename, ContentImporterContext context)
{
using (var xmlReader = XmlReader.Create(filename))
{
return IntermediateSerializer.Deserialize<SpriteData>(xmlReader, filename);
}
}
}
And a SpriteProcessor
as:
[ContentProcessor(DisplayName = "Sprite Processor")]
public class SpriteProcessor : ContentProcessor<SpriteData, SpriteData>
{
public override SpriteData Process(SpriteData input, ContentProcessorContext context)
{
var spritePath = Path.GetDirectoryName(context.OutputFilename);
var textureReference = new ExternalReference<Texture2DContent>(input.TextureFilename);
// make sure the texture is built (not sure what else to do here)
context.BuildAsset<Texture2DContent, Texture2DContent>(textureReference, string.Empty);
return input;
}
}
Now I'm stuck. If I don't implement a content writer+reader combination then I won't get a Sprite
out of the content manager - I'll get a SpriteData
instead, which is not what I want. But my attempt to implement a SpriteWriter
came up short. I have no idea how to get the texture information from the processor to the writer. Do I need to change the type from SpriteData
to something else? Is there a sample anywhere that demonstrates how to do this end-to-end?