-1

The message:

Unable to cast object of type 'Microsoft.Xna.Framework.Graphics.Effect' to type 'Microsoft.Xna.Framework.Graphics.BasicEffect'

The code:

foreach (ModelMesh mesh in xwingModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (BasicEffect Effects in mesh.Effects)
                {
                    Effects.EnableDefaultLighting();
                    Effects.World = transforms[mesh.ParentBone.Index] *
                        //Matrix.CreateRotationY(modelRotation)
                         Matrix.CreateTranslation(modelPosition);
                    Effects.View = Matrix.CreateLookAt(cameraPosition,
                        Vector3.Zero, Vector3.Up);
                    Effects.Projection = Matrix.CreatePerspectiveFieldOfView(
                        MathHelper.ToRadians(45.0f), aspectRatio,
                        1.0f, 10000.0f);
                }
                // Draw the mesh, using the effects set above.
                mesh.Draw();
            }

The exception is on this part:

BasicEffect Effects

The full exception message:

System.InvalidCastException was unhandled
  HResult=-2147467262
  Message=Unable to cast object of type 'Microsoft.Xna.Framework.Graphics.Effect' to type 'Microsoft.Xna.Framework.Graphics.BasicEffect'.
  Source=MyFlightSimulator
  StackTrace:
       at MyFlightSimulator.Game1.DrawModel() in Game1.cs:line 279
       at MyFlightSimulator.Game1.Draw(GameTime gameTime) in Game1.cs:line 133
       at Microsoft.Xna.Framework.Game.DrawFrame()
       at Microsoft.Xna.Framework.Game.Tick()
       at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
       at Microsoft.Xna.Framework.GameHost.OnIdle()
       at Microsoft.Xna.Framework.WindowsGameHost.RunOneFrame()
       at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
       at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Microsoft.Xna.Framework.WindowsGameHost.Run()
       at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
       at Microsoft.Xna.Framework.Game.Run()
       at MyFlightSimulator.Program.Main(String[] args) in Program.cs:line 15
  InnerException: 

Game1 line 279 is:

foreach (BasicEffect Effects in mesh.Effects)

Program line 15 is:

game.Run();

This is the complete method code:

private void DrawModel()
        {
            Matrix[] transforms = new Matrix[xwingModel.Bones.Count];
            xwingModel.CopyAbsoluteBoneTransformsTo(transforms);

            // Draw the model. A model can have multiple meshes, so loop.
            foreach (ModelMesh mesh in xwingModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (BasicEffect Effects in mesh.Effects)
                {
                    Effects.EnableDefaultLighting();
                    Effects.World = transforms[mesh.ParentBone.Index] *
                        //Matrix.CreateRotationY(modelRotation)
                         Matrix.CreateTranslation(modelPosition);
                    Effects.View = Matrix.CreateLookAt(cameraPosition,
                        Vector3.Zero, Vector3.Up);
                    Effects.Projection = Matrix.CreatePerspectiveFieldOfView(
                        MathHelper.ToRadians(45.0f), aspectRatio,
                        1.0f, 10000.0f);
                }
                // Draw the mesh, using the effects set above.
                mesh.Draw();
            }
        }
Shiran Yeyni
  • 35
  • 2
  • 9
  • Updated my question with full code and if i change it to Effect in the foreach then Effects dosent have all the properties in the next lines. – Shiran Yeyni Aug 12 '14 at 20:12

4 Answers4

3

some or all elements of mesh.Effects are not a BasicEffect but an Effect object

Try this

foreach (Effect ItemEffect in mesh.Effects)
{
   if ( (ItemEffect is BasicEffect) == false)
       continue;

    BasicEffect Effects = (BasicEffect)ItemEffect;

    Effects.EnableDefaultLighting();
    Effects.World = transforms[mesh.ParentBone.Index] *

    Matrix.CreateTranslation(modelPosition);
    Effects.View = Matrix.CreateLookAt(cameraPosition,Vector3.Zero, Vector3.Up);
    Effects.Projection = Matrix.CreatePerspectiveFieldOfView(
                    MathHelper.ToRadians(45.0f), aspectRatio,
                    1.0f, 10000.0f);
}
tdelepine
  • 1,986
  • 1
  • 13
  • 19
  • Updated my question with full code and if i change it to Effect in the foreach then Effects dosent have all the properties in the next lines. – Shiran Yeyni Aug 12 '14 at 20:11
2

As described in this post: XNA Apply effect on BasicEffect not all Effects are BasicEffects.

foreach(BasicEffect basicEffect in mesh.Effects.OfType<BasicEffect>())
{

}
Community
  • 1
  • 1
Martijn van Put
  • 3,293
  • 18
  • 17
1

What type of objects are contained in mesh.Effects? From the MSDN documentation, BasicEffect inherits from Effect, so if all of the elements in mesh.Effects are of the type BasicEffect, the code should work.

Most likely an element in mesh.Effects is not a BasicEffect.

Double check what is in that list, or make sure you only run your code on the BasicEffects by casting them using the as operator and checking if they are not null, in which case they are a BasicEffect

foreach (BasicEffect Effects in mesh.Effects)
{
     BasicEffect basicEffect = Effects as BasicEffect;
     if (basicEffect != null)
     {
          //Effects is a BasicEffect, run code on basicEffect
     }
}

You can also use LINQ's OfType to select only the effects in the mesh that are BasicEffects

foreach (BasicEffect Effects in mesh.Effects.OfType<BasicEffect>());
{
     //Run code on Effects
}
Cyral
  • 13,999
  • 6
  • 50
  • 90
0

Not every member of the set is castable to BasicEffect but you can avoid those:

foreach(var effect in mesh.Effects.Where(e => e.GetType().IsAssignableFrom(Effect).ToList())
    YourFunctionOrWhatever();

If you're reading this, check Martijn's answer instead. It's prettier :)

clarkitect
  • 1,720
  • 14
  • 23