XNA Content Pipeline using VB.NET
Using the XNA Content Pipeline in Visual Basic .Net 2008
This page is obselete, please check: XNA in VB .Net
The Content Pipeline is the part where most people get stuck in Visual Basic.
The content pipeline is nothing more than a project that you can add to your visual basic solution. Your solution can be multilanguaged, for instance, you can have a visual basic project in there and also have a c# project in there; which is another great advantage in the Visual Studio environment. So to start a Visual Basic XNA Project, I've done the following steps (about 20 steps):
1- Create a new Visual Basic Project, Select a standard Windows Form project and save it somewhere (I'll refer to this location as %SolutionRoot%)
2- Remove the form
3- Go to your project properties and set your Startup Object to "Sub Main". If you can't select Sub Main, change your project type to "Console Application", close the properties, save the project and go back to the properties and select Sub Main as Startup Object and Windows Form Application again as Project Type. Then save it again.
4- Right click on your project name in the solution explorer and select "Add references". (Or go to the menu Project >> Add references)
5- In the list search for Microsoft.XNA, and select all the XNA components you can find in that list
6- Also add the following references:
Microsoft.VisualBasic.Compatibility System System.Core System.Windows.Forms (Should already be there) System.XML System.XML.Linq
7- Add a module and give it a name (like "Program.vb")
8- Add a class and call this one "Game1"
9- Open the Program.vb module and add this code (This is translated from an original XNA C# project)
Option Explicit On
Module Program
'/// The main entry point for the application.
Public Sub Main(ByVal args() As String)
Dim game As New Game1()
game.Run()
End Sub
End Module
10- Open your Game1 class and add this code (This is also translated from an original XNA C# project)
Option Explicit On
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Audio
Imports Microsoft.Xna.Framework.Content
Imports Microsoft.Xna.Framework.GamerServices
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Media
Imports Microsoft.Xna.Framework.Net
Imports Microsoft.Xna.Framework.Storage
'Namespace WindowsXNAGame1 ' You can add a namespace, but it's not required.
'/// This is the main type for your game
Public Class Game1
Inherits Microsoft.Xna.Framework.Game
Dim graphics As GraphicsDeviceManager
Dim spriteBatch As SpriteBatch
Public Sub New()
graphics = New GraphicsDeviceManager(Me)
Content.RootDirectory = "Content"
End Sub
'/// Allows the game to perform any initialization it needs to before starting to run.
'/// This is where it can query for any required services and load any non-graphic
'/// related content. Calling base.Initialize will enumerate through any components
'/// and initialize them as well.
Protected Overrides Sub Initialize()
'// TODO: Add your initialization logic here
MyBase.Initialize()
End Sub
'/// LoadContent will be called once per game and is the place to load
'/// all of your content.
Protected Overrides Sub LoadContent()
MyBase.LoadContent()
'// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = New SpriteBatch(GraphicsDevice)
'// TODO: use this.Content to load your game content here
End Sub
'/// UnloadContent will be called once per game and is the place to unload
'/// all content.
Protected Overrides Sub UnloadContent()
MyBase.UnloadContent()
'// TODO: Unload any non ContentManager content here
End Sub
'/// Allows the game to run logic such as updating the world,
'/// checking for collisions, gathering input, and playing audio.
Protected Overrides Sub Update(ByVal gameTime As GameTime)
'// Allows the game to exit
If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then _
Me.Exit()
If Keyboard.GetState().IsKeyDown(Keys.Escape) Then _
Me.Exit()
'// TODO: Add your update logic here
MyBase.Update(gameTime)
End Sub
'/// This is called when the game should draw itself.
Protected Overrides Sub Draw(ByVal gameTime As GameTime)
GraphicsDevice.Clear(Color.CornflowerBlue)
'// TODO: Add your drawing code here
MyBase.Draw(gameTime)
End Sub
End Class
'End Namespace
11- Save and hit the F5 key. There, you've got your cornflower blue window. Hit the Escape key to exit. We're not ready just yet. Now we need to add the content pipeline, which are another few steps
First however, we need to create the project for it. You can do it from scratch if you like, but I found that the easiest way is by creating a new project, this time in C#
1- Open a new instance of Visual Studio, and create a new C# Project. Click XNA Framework in the Project Type pane and click the Windows Game in the Template pane. Project name and location isn't important, as we're not going to use this project for our game.
2- Save the project and close this Visual Studio
3- Browse to the location of your C# project and copy the "Content" folder into your VB project folder (By default %SolutionRoot%/%ProjectName%/)
4- Go back to the Visual Studio of your VB project and go to File >> Add >> Existing Project
5- Browse to the Content folder in your VB Project folder.
6- If you don't see anything there, type *.* into the Filename (Or objectname) and hit the enter key, select Content.contentproj from the list and click open
7- Save your Visual Basic solution.
You'll notice that your project is converted into a solution and that the Content Pipeline is now available from your solution explorer. We need to adjust 1 more thing before you can use the content pipeline properly. Close Visual Studio and open the Content.contentproj file (In the "Content" folder) with your favorite text editor (Like ultra edit or notepad or whatever you like)
If you browse to your solution folder, the directory structure will be something like this:
.\ProjectName .\ProjectName\Bin .\ProjectName\Bin\Debug .\ProjectName\Bin\Release .\ProjectName\Content Etcetera
Keep this in mind. We need to change the path to where Content should put its compiled asset files. In our case in .\ProjectName\Bin\(Either debug or release), because that's where the game will be compiled to. So in your text editor (the Content.contentproj file) find this line:
<OutputPath>bin\$(Platform)\$(Configuration)</OutputPath>
And change it to:
<OutputPath>..\bin\$(Configuration)</OutputPath>
Save the file and open your Visual Basic solution again.
There your content pipeline is ready for use.
Add textures, fonts, meshes, sounds and other stuff like you would in a normal C# project, and when you compile your solution, everything will work they way it should work in C#
To build your project with the content, go to the menu Build >> Build Solution.
One more thing. If you want to load something from the content pipeline in your VB project, do it like this: MySprite = Content.Load(Of Texture2D)("Sprites\SomeSprite")
The "Of Texture2D" might be something new in vb to some people (it was for me). It's the way how Visual Basic interacts with generics. Also don't use "\\" in your path names, because that's only for C based languages (where "\" is a cancel character).
Known issues
- Please note that this does not work on 64-bit systems. It appears that Visual Basic .Net on Vista 64-bit will throw an exception at runtime before the application is even initialized.
Exception thrown:
System.IO.FileNotFoundException was unhandled
FileName="Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d"
FusionLog="=== Pre-bind state information === LOG: User = PC\Administrator LOG: DisplayName = Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d (Fully-specified) LOG: Appbase = file:///E:/Documents/PubliUser/My Programs/VB .NET/WindowsXNAGame1/WindowsXNAGame1/WindowsXNAGame1/bin/Debug/ LOG: oorspronkelijk PrivatePath = NULL Aanroep-assembly : Microsoft.Xna.Framework.Game, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d. === LOG: This bind starts in default load context. LOG: no application configuration file found. LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config wordt gebruikt. LOG: Post-policy reference: Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d LOG: The same bind was seen before, and was failed with hr = 0x80070002. "
Message="Could not load file or assembly, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d or one of its dependencies. The system cannot find the file specified."
Source="WindowsXNAGame1"
StackTrace:
at Project1.Game1..ctor()
at Project1.WindowsXNAGame1.Program.Main(String[] args) in E:\My Programs\VB .NET\WindowsXNAGame1\WindowsXNAGame1\WindowsXNAGame1\Program.vb:line 10
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
A work around for this would involve working with client dll writting in vb .net compiled as a class library and then referenced in the C# project (See next section)
(Vista) 64-bit Work around to the "System.IO.FileNotFoundException" problem
Please see article XNA in VB .Net