Moving forward, the tutorials on this website will be referencing XNA 2.0.
Here is an updated version of the VBContentManager class for use with XNA 2.0
The class itself now inherits from the XNA 2.0 ContentManager
The LoadPipeline() method has been replaced by the CompileContent & LoadAllContent methods. Call these methods as appropriate where LoadPipeline was used before.
You can now specify a platform (Windows or Xbox360), although it's not exactly known whether or not you can run VB.NET on an Xbox360. This is there just in case/for the future. The target platform is Windows by default
You can now specify whether or not the MSBuild window is visible, having the content compile in "stealth mode" (as a C# project does)
The content folder is no longer supplied relative to the bin\Debug folder. You now supply it relative to the Project node in which the folder resides. For example, if you made a folder called "My Content" in your game's project in the Solution Explorer, you would simply supply "My Content" as the path to your content (rather than "../../My Content" like before)
The 'fake' project file built for MSBuild is now a .contentproj file, rather than an actual .csproj file. Not that the extension matters much, this was simply for the sake of emulating the file created in XNA 2.0 (where, in C#, content is now a sub-project of the game and has it's own project file - the VBContentManager simply simulates this file). As an aside, the project file being generated is more well formed than before, so MSBuild should no longer throw warning messages as it compiles.
In the previous version of the VBContentManager, choosing not to compile the content would result in a runtime error. You no longer have to compile the content; if you know it's already compiled (like say for instance, right before you are going to distribute the application to someone's PC) you can omit the call to CompileContent in your code and load the already-compiled content (skips the call to MSBuild completely).
Public Fonts As Hashtable(Of SpriteFont) Public Textures As Hashtable(Of Texture2D) Public SubTextures As Hashtable(Of Hashtable(Of Rectangle)) Public Sounds As Hashtable(Of SoundBank) Public Effects As Hashtable(Of Effect)
Private strContentprojFile, strProjectFolder, strExecutingFolder, strContentFolder As String Private objContent As List(Of ContentFile) Private intDupeSound, intDupeTexture, intDupeFont, intDupeEffect AsInteger
Public ContentType As ContentTypes Public File As System.IO.FileInfo Public Name As String
PublicSubNew(ByVal ContentType As ContentTypes, ByVal ContentFile As System.IO.FileInfo, ByVal Name As String) Me.ContentType = ContentType Me.File = ContentFile Me.Name = Name EndSub
EndStructure
''' <summary> ''' Creates a new ContentManager which has been extended with functionality to support a Visual Basic (or other non-C#) project ''' </summary> ''' <param name="ServiceProvider">Your game has a .Services property; send that in here.</param> ''' <param name="ContentFolder">Your content folder (a relative path, from your game's Project node as it appears in the Solution Explorer)</param> ''' <remarks></remarks> PublicSubNew(ByVal ServiceProvider As IServiceProvider, ByVal ContentFolder As String)
MyBase.New(ServiceProvider)
With System.Reflection.Assembly.GetEntryAssembly.Location Me.strExecutingFolder = .Substring(0, .LastIndexOf("\")) EndWith
Me.Fonts = New Hashtable(Of SpriteFont) Me.Textures = New Hashtable(Of Texture2D) Me.SubTextures = New Hashtable(Of Hashtable(Of Rectangle)) Me.Sounds = New Hashtable(Of SoundBank) Me.Effects = New Hashtable(Of Effect)
EndSub
''' <summary> ''' Attempts to load all assets which have been compiled by the Content Pipeline. Assets are placed into the respective Hash table (Fonts, Textures, et al) ''' </summary> ''' <remarks></remarks> PublicSub LoadAllContent()
Dim objCompiledContent AsNew List(Of IO.FileInfo) Dim strUnknownFiles As String = ""
ForEach file As IO.FileInfo InNew IO.DirectoryInfo(Me.strExecutingFolder).GetFiles("*.xnb", IO.SearchOption.AllDirectories)
MsgBox("The VBContentManager was unable to determine the correct loader for:" & vbCrLf & _ strUnknownFiles & vbCrLf & vbCrLf & _ "Unless loaded by something else, the above content won't be available at runtime." & vbCrLf & vbCrLf & _ "This application may become unstable as a result.")
EndIf
EndSub
''' <summary> ''' Compiles the VB Content Pipeline ''' </summary> ''' <param name="stealth">Hide/Show the MSBuild window during the compile process</param> ''' <param name="platform">If there's a way the Xbox360 will work with VB, you could pass in the Xbox parameter as a target platform to MSBuild. But it's Windows by default.</param> ''' <remarks></remarks> PublicSub CompileContent(ByVal stealth AsBoolean, OptionalByVal platform As Platform = VBContentManager.Platform.Windows)
Dim objProcess As Process Dim objPSI AsNew Diagnostics.ProcessStartInfo
Me.objContent = New List(Of ContentFile)
Me.HarvestContent()
IfMe.objContent.Count > 0 Then
Me.BuildContentProj(platform)
Try 'to write the content project file to disk
Using TempStreamWriter As System.IO.StreamWriter = New System.IO.StreamWriter(Me.strProjectFolder & "\Content.contentproj", False)
With TempStreamWriter
.Write(Me.strContentprojFile) .Close()
EndWith
EndUsing
Try
With objPSI .FileName = Environment.GetEnvironmentVariable("Windir") & "\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe" .Arguments = """" & Me.strProjectFolder & "\Content.contentproj""" & _ " /verbosity:normal" & _ " /l:FileLogger,Microsoft.Build.Engine;logfile=""" & Me.strProjectFolder & "\Content.log""" If stealth Then .Arguments &= " /noconsolelogger" EndIf If stealth Then .WindowStyle = ProcessWindowStyle.Hidden EndIf EndWith
MsgBox("When building the pipeline, trying to run MSBuild.exe resulted in: " & ex.Message)
EndTry
Catch ex As Exception
MsgBox("When building the pipeline, trying to create the Content.contentproj file """ & Me.strContentFolder & "\Content.contentproj"" resulted in: " & ex.Message)
EndTry
EndIf
EndSub
PrivateSub HarvestContent()
Dim objRoot As System.IO.DirectoryInfo = New System.IO.DirectoryInfo(Me.strContentFolder)
ForEach sound As System.IO.FileInfo In objRoot.GetFiles("*.xab", IO.SearchOption.AllDirectories) IfMe.objContent.Contains(New ContentFile(ContentTypes.Sounds, sound, sound.Name.Replace(sound.Extension, ""))) Then Me.intDupeSound += 1 Me.objContent.Add(New ContentFile(ContentTypes.Sounds, sound, sound.Name.Replace(sound.Extension, "") & Me.intDupeSound.ToString)) Else Me.objContent.Add(New ContentFile(ContentTypes.Sounds, sound, sound.Name.Replace(sound.Extension, ""))) EndIf Next
ForEach texture As System.IO.FileInfo In objRoot.GetFiles("*.png", IO.SearchOption.AllDirectories) IfMe.objContent.Contains(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, ""))) Then Me.intDupeTexture += 1 Me.objContent.Add(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, "") & Me.intDupeTexture.ToString)) Else Me.objContent.Add(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, ""))) EndIf Next
ForEach texture As System.IO.FileInfo In objRoot.GetFiles("*.jpg", IO.SearchOption.AllDirectories) IfMe.objContent.Contains(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, ""))) Then Me.intDupeTexture += 1 Me.objContent.Add(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, "") & Me.intDupeTexture.ToString)) Else Me.objContent.Add(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, ""))) EndIf Next
ForEach texture As System.IO.FileInfo In objRoot.GetFiles("*.gif", IO.SearchOption.AllDirectories) IfMe.objContent.Contains(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, ""))) Then Me.intDupeTexture += 1 Me.objContent.Add(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, "") & Me.intDupeTexture.ToString)) Else Me.objContent.Add(New ContentFile(ContentTypes.Textures, texture, texture.Name.Replace(texture.Extension, ""))) EndIf Next
ForEach font As System.IO.FileInfo In objRoot.GetFiles("*.spritefont", IO.SearchOption.AllDirectories) IfMe.objContent.Contains(New ContentFile(ContentTypes.Fonts, font, font.Name.Replace(font.Extension, ""))) Then Me.intDupeFont += 1 Me.objContent.Add(New ContentFile(ContentTypes.Fonts, font, font.Name.Replace(font.Extension, "") & Me.intDupeFont.ToString)) Else Me.objContent.Add(New ContentFile(ContentTypes.Fonts, font, font.Name.Replace(font.Extension, ""))) EndIf Next
ForEach effect As System.IO.FileInfo In objRoot.GetFiles("*.fx", IO.SearchOption.AllDirectories) IfMe.objContent.Contains(New ContentFile(ContentTypes.Effects, effect, effect.Name.Replace(effect.Extension, ""))) Then Me.intDupeEffect += 1 Me.objContent.Add(New ContentFile(ContentTypes.Effects, effect, effect.Name.Replace(effect.Extension, "") & Me.intDupeEffect.ToString)) Else Me.objContent.Add(New ContentFile(ContentTypes.Effects, effect, effect.Name.Replace(effect.Extension, ""))) EndIf Next
EndSub
PrivateSub BuildContentProj(ByVal platform As Platform)
To see how a Game can utilize the VBContentManager class, see , and then read the change log at the top of this post.
Some slight changes can be made to the MyBaseGame class as well. Now that a ContentManager is built into v2.0 of the XNA Game class, you can overload the Content property to return your VBContentManager.
1 comments:
said...
Hi, I have created a C# version of the Hashtable (or should I say modified it) and ContentManger Class. I have a converted C# version of the engine in progress. As you can guess some minor differences. Btw my version also runs with VB no difference. I hope to use it as training tool for young developers. Thanks to XNA Machine as I am learning so much from you, keep up the good work.
1 comments:
Hi, I have created a C# version of the Hashtable (or should I say modified it) and ContentManger Class. I have a converted C# version of the engine in progress. As you can guess some minor differences. Btw my version also runs with VB no difference. I hope to use it as training tool for young developers. Thanks to XNA Machine as I am learning so much from you, keep up the good work.