为什么我得到异常InvalidCastException
本文关键字:异常 InvalidCastException 为什么 | 更新日期: 2023-09-27 18:17:46
留言:
无法强制转换类型为"Microsoft.Xna.Framework.Graphics"的对象。"Microsoft.Xna.Framework.Graphics.BasicEffect"
代码:
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();
}
例外是在这部分:
BasicEffect影响
完整异常消息:
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第279行是:
foreach (BasicEffect Effects in mesh.Effects)
程序第15行是:
game.Run();
完整的方法代码:
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();
}
}
部分或全部网格元素。Effects不是BasicEffect,而是Effect对象
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);
}
如本文所述:XNA在BasicEffect上应用效果并非所有效果都是BasicEffects。
foreach(BasicEffect basicEffect in mesh.Effects.OfType<BasicEffect>())
{
}
mesh.Effects
中包含什么类型的对象?从MSDN文档中,BasicEffect
继承自Effect
,因此如果mesh.Effects
中的所有元素都是BasicEffect
类型,则代码应该可以工作。
mesh.Effects
中的元素很可能是而不是 BasicEffect
。
仔细检查列表中的内容,或者确保您只在BasicEffect
上运行代码,使用as
操作符强制转换它们并检查它们是否为空,在这种情况下它们是BasicEffect
foreach (BasicEffect Effects in mesh.Effects)
{
BasicEffect basicEffect = Effects as BasicEffect;
if (basicEffect != null)
{
//Effects is a BasicEffect, run code on basicEffect
}
}
你也可以使用LINQ的OfType
来选择网格中BasicEffect
s的效果
foreach (BasicEffect Effects in mesh.Effects.OfType<BasicEffect>());
{
//Run code on Effects
}
并不是集合的每个成员都可以转换为BasicEffect,但是你可以避免它们:
foreach(var effect in mesh.Effects.Where(e => e.GetType().IsAssignableFrom(Effect).ToList())
YourFunctionOrWhatever();
如果你正在读这篇文章,看看马丁的回答。它更漂亮了:)