In this tutorial, we're going to cover how to load content into your game. We'll get into the details in a minute, but this is a piece of MonoGame that doesn't work nearly as well as it should. Basically, as of MonoGame version 3.2, we still have to piggyback off of XNA's content pipeline.
In the previous tutorial, I showed you how to set up XNA and XNA's content pipeline. If you haven't already done that, go back and do it now.
Now that we've got that step done, though, we're ready to pull in content from XNA's content pipeline.
The good news is, MonoGame 3.2 integrates with XNA's content pipeline than earlier versions of MonoGame, and the upcoming releases are focused on getting their own content pipeline in place. (Though no promises on when that will actually happen.)
Creating a Content Project
When we created our first MonoGame project, the solution that was built contained only one project. You can view this in the Solution Explorer:
The solution is named the same thing as the project ("MyFirstGame" in the image above) but don't let that confuse you. A solution is a collection of one or more projects that work together. So far, it's only one, but in this tutorial, we'll add in a couple of additional projects to get our content up and running.
Our first step is to create a content project for our game.
To do this, right-click on the top solution node in the Solution Explorer (not the project node by the same name underneath it) and choose Add > New Project….
This brings up the New Project dialog again, which we saw before. This time, instead of adding a new MonoGame Windows Project, you'll add a new MonoGame Content Project.
You'll also give your project a name. Traditionally, you might choose a project name that matches your game's name but with "Content" stuck on the end, though that gives us a strange artifact that we'll see in a second. I'll assume that's what you've done for the time being, but if you don't like the artifact (which I'll describe in a second) you can delete the projects that get created and start over with a different name.
After you do this, you'll see not one, but two new projects added to your solution, for a total of 3 projects:
Now here's the dumb artifact that I mentioned earlier. You get two projects, one is called "MyFirstGameContent" and the other is called "MyFirstGameContentContent". It's unfortunate that there has to be two projects to get this working, and it's kind of obnoxious that you now have a project name that ends in "ContentContent".
The "ContentContent" project is the actual content project. (It would be better if this piece could be the only one, but it doesn't really work that way.) This is where you'll eventually place your art assets for use in your game.
The other project ("MyFirstGameContent") is an intermediary project that gets things linked correctly. (Through that Content References node.)
So you really need both of those for this to function.
If you'd rather not have a "ContentContent" project (I don't blame you) you can delete these (be sure to also delete them on disk, in addition to deleting them from the Solution Explorer) and start over with a different name.
Linking Your Content Project to Your Main Game
We've added the content project, and we're almost ready to go. But there's one link that's still missing. Our main game project (the one called "MyFirstGame" in the screenshots) doesn't know about the content project yet. We have to tell it to pull it in as a dependency.
This is pretty easy to do.
Go back to the Solution Explorer and look under the "MyFirstGame" project node for the one called References (highlighted in the image below).
Right-click on this node and choose Add Reference….
This brings up the Reference Manager dialog. In here, you can manage all of the references that your game has, but in particular, you want to add a reference to that content intermediary project. You can do that by making sure the Solution / Projects element is selected on the left, and check the box by the content project's name.
When you've got it checked, press OK to close the dialog.
If you open the References node, you will now see the reference to the content project in the list:
Adding Assets to your Project
With an XNA content project set up, you can now add art assets to it. By default, XNA supports the following file types, and MonoGame should be able to take advantage of all of them as well:
|Content Type||File Types|
|3D Models||.x, .fbx|
|Textures/Images||.bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, .tga|
|Audio||.xap (an XACT audio project), .wma, .mp3, .wav|
Whatever content files you want to add, simply drag and drop them into the content project (the one that ended in "ContentContent".
You may find it useful to organize your content into folders. To add a folder, right-click on the content project (note that the top level element in the solution explorer is your "solution", which can contain multiple projects—the content project is the second item inside of that), and choose Add > New Folder.
It is probably also worth pointing out that you can add existing files this way as well, instead of just dragging and dropping them into the project. And for a few things, such as .spritefont and .fx files, you can choose Add > New Item… as well. We'll cover those in more detail as they're needed.
Note that there are ways to extend the content pipeline if it doesn't already import the file types you need, but that's really a discussion for another day. In all likelyhood, you won't need that right away. The current XNA content pipeline is good enough for many games.
For the purposes of practicing how this works, and also to make sure that everything is working like it should, add an image into the content project now, before proceeding on.
Loading Content in MonoGame
OK, now we are on to the real interesting part. We are now going to use the content we just added. In other tutorials, as we talk about using each of the different kinds of content in turn, we will discuss this in greater detail. For now, though, we will just do something simple. Loading content in your game is always done in about the same way. Go to your LoadContent() method in your game, and add the following line (replacing [FileNameWithoutExtension] with the name of your file in quotes):
Texture2D image = Content.Load<Texture2D>("[FileNameWithoutExtension]");
A Texture2D object is simply a way of storing a picture. A texture is the computer graphics term for an image that you place on a 3D object, which is one of the most common ways of using an image. There are other ways to use a Texture2D object, as well. We will talk a little more about this in other tutorials. All we really need to do to load our content is call the function Content.Load(), with the name of the asset that we want to load. In the angle brackets ("<" and ">") we put the type of content that we are loading, which in this case, is simply a Texture2D as well.
You do not need to put the extension on the file! In XNA, you could not put the extension in. In MonoGame, you can, but I'd still recommend against it. As MonoGame's content pipeline progresses, if they make it more like the XNA content pipeline, you'll have to strip out the extensions, which won't be fun.
Also, if you have put your content in different directories, you will need to put the path to the file as well. For example, if our image was called Logo in a directory called Backgrounds, we would need to say:
Texture2D image = Content.Load<Texture2D>("Backgrounds/Logo");
Unloading Content in your Game
For a small game, you may not ever need to unload any content in your game. However, if you have a big game, you can't just keep loading more and more content and expect it to keep working. It is a good idea to unload unnecessary content whenever you are done using it. So, for instance, you can unload all of the content for a particular level, after the level is completed, so that there is room for the next level's content to be loaded.
To do this, simply add the following line to your program:
This frees up (almost) all of the content that was loaded by your content manager. Of course, this means that if you want to reuse something that was previously loaded, you will need to load it again.
It might be a good idea to create multiple ContentManager objects to divide up the content. That way you can call Unload() for the ContentManagers that you are done with.
Even if you don't have a big game, it is still doesn't hurt to unload unused content.
We've discussed how you can load content or art assets in your MonoGame project. This will make it easy to start working on your game, which we're now ready to do!
|Having problems with this tutorial? Try the troubleshooting page!|