1
\$\begingroup\$

I am sorry, because I know, that this question came up before, but that thread doesn't help me so I decided to aks my own question.

My problem is the following: I have a XML-file with the following content:

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent xmlns:Generic="System.Collections.Generic">
<Asset Type="System.Collections.Generic.List[ArenaFighterClasses.Weapon]">
<item>
  <Name>Pistole</Name>
  <Strength>5.0</Strength>
  <Cadency>300</Cadency>
  <ImageName>gfx/Weapons/Weapon1</ImageName>
  <BulletImageName>gfx/Weapons/Bullets/Bullet1</BulletImageName>
</item>

<item>
  <Name>MG</Name>
  <Strength>7.0</Strength>
  <Cadency>100</Cadency>
  <ImageName>gfx/Weapons/Weapon1</ImageName>
  <BulletImageName>gfx/Weapons/Bullets/Bullet1</BulletImageName>
</item>

<item>
  <Name>Shotgun</Name>
  <Strength>10.0</Strength>
  <Cadency>500</Cadency>
  <ImageName>gfx/Weapons/Weapon1</ImageName>
  <BulletImageName>gfx/Weapons/Bullets/Bullet1</BulletImageName>
</item>

Now I have the class Weapon (as you can see in the tag). But everytime I try to compile my project I get the following errormessage:

There was an error while deserializing intermediate XML. Cannot find type "ArenaFighterClasses.Weapon".

I don't know where this error comes from. I did it the following way: I have my main project, where all the content like images, sounds and xml files is. Then, in the same projec map I have another Project with all the classes. And, finally in the same project map there is a project of the type Content Pipeline Extension Library in which the ContentTypeWriter for the Weapon is written.

Here is the code of the ContentTypeWriter:

  namespace XMLContentExtension
  {
  /// <summary>
  /// This class will be instantiated by the XNA Framework Content Pipeline
  /// to write the specified data type into binary .xnb format.
  ///
  /// This should be part of a Content Pipeline Extension Library project.
  /// </summary>
  [ContentTypeWriter]
  public class WeaponContentWriter : ContentTypeWriter<Weapon>
  {
    protected override void Write(
            ContentWriter output,
            Weapon value)
    {
        output.Write(value.Name);
        output.Write(value.Strength);
        output.Write(value.Cadency.Milliseconds);
        output.Write(value.ImageName);
        output.Write(value.BulletImageName);
    }

    public override string GetRuntimeReader(
            TargetPlatform targetPlatform)
    {
        return typeof(WeaponContentReader).AssemblyQualifiedName;
    }
   } 
  }

And this is the relevant Code of the Weapon class and the ContentTypeReader:

 namespace ArenaFighterClasses
 {
 public class Weapon : GameEntity
 {
    #region Static Fields
    //Fields used to initialize this class
    public static string sXMLPlayerWeaponsFileName = "XML/PlayerWeapons";
    public static string sXMLEnemyWeaponsFileName = "XML/EnemyWeapons";
    public static List<Weapon> lwPlayerWeaponsTemplate = new List<Weapon>();
    public static List<Weapon> lwEnemyWeaponsTemplate = new List<Weapon>();
    #endregion


    #region Static Methods
    public static void InitalizeWeapons(ContentManager pConMan)
    {
        lwPlayerWeaponsTemplate = pConMan.Load<List<Weapon>>    
                 (sXMLPlayerWeaponsFileName);
    }
    #endregion

    public Weapon(string pName)
    {
        Name = pName;
        Strength = 0.0f;
        Cadency = TimeSpan.Zero;
        ElapsedTime = TimeSpan.Zero;
        Rotation = 0.0f;
        Speed = 0.0f;
        Position = Vector2.Zero;
        BulletImageName = "";
        ImageName = "";
        Image = null;
        BulletImage = null;
        BulletImage.IsActive = false;

    }

    public Weapon()
    {
        Name = "";
        Strength = 0.0f;
        Cadency = TimeSpan.Zero;
        ElapsedTime = TimeSpan.Zero;
        Rotation = 0.0f;
        Speed = 0.0f;
        Position = Vector2.Zero;
        BulletImageName = "";
        ImageName = "";
        Image = null;
        BulletImage = null;
        BulletImage.IsActive = false;
    }

    public override void Update(GameTime gameTime)
    {
        Image.Update(gameTime);
    }

    public void LoadImages(ContentManager pConMan)
    {
        Image = new IngameImage(pConMan.Load<Texture2D>(ImageName), Position, 16, 
                                 16, 1, 0, Color.White, 1.0f, true);
        BulletImage = new IngameImage(pConMan.Load<Texture2D>(BulletImageName), 
             Position, 8, 8, 1, 0, Color.White, 1.0f, true);
    }
}

public class WeaponContentReader : ContentTypeReader<Weapon>
{
    protected override Weapon Read(ContentReader input, Weapon existingInstance)
    {
        Weapon weapon = new Weapon();

        weapon.Name = input.ReadString();
        weapon.Strength = (float)input.ReadDouble();
        weapon.Cadency = TimeSpan.FromMilliseconds(input.ReadInt32());
        weapon.ImageName = input.ReadString();
        weapon.BulletImageName = input.ReadString();

        weapon.LoadImages(input.ContentManager);

        return weapon;
    }
  }
 }

I really hope someone can help me, because I really have no more idea what to do.

For everybody who speaks german (sorry, but the english tutorial is no more available) here is the tutorial where my code is based on: http://www.xnamag.de/article.php?aid=26

\$\endgroup\$
2
  • \$\begingroup\$ Change the second line to <XnaContent xmlns:Generic="System.Collections.Generic" xmlns:ArenaFighterClasses="ArenaFighterClasses"> and try again. \$\endgroup\$
    – Blecki
    Nov 9, 2011 at 1:29
  • 1
    \$\begingroup\$ Also, you don't need to write custom writers and readers as of, I think, xna 3.0. The only thing yours appears to be doing that the 'default' ones don't is loading some images. Regardless, these types are for writing and reading the binary XNB, and shouldn't be related to parsing the XML in any way. \$\endgroup\$
    – Blecki
    Nov 9, 2011 at 1:32

1 Answer 1

2
\$\begingroup\$

This one is pretty simple. Your content project (not the content pipeline extension) needs to have a reference to the assembly (or project) that contains the Weapon type.

Because your game will depend on both the Weapon type and the content project, you will need to put the Weapon type in an assembly that is separate from the game itself.

\$\endgroup\$
2
  • \$\begingroup\$ Sorry, but I don't really understand what exactly you mean. I have my main project where all my images etc. are. Then an Game Library where all the classes for the game are. And the Content Pipeline Extension Library where the ContentTypeWriter is. I am sorry, but where has to be what now? \$\endgroup\$ Nov 9, 2011 at 8:25
  • \$\begingroup\$ Thank you very much. I found a solution: I had to add a reference in the CONTENT-references and not in the normal references. \$\endgroup\$ Nov 9, 2011 at 9:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .