XNA Content Pipeline using VB.NET

From XNAWiki
Jump to: navigation, search

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