我的相机怎么了?
本文关键字:怎么了 相机 我的 | 更新日期: 2023-09-27 18:03:43
我使用VS2010与c#和XNA 4.0。我正在阅读Aaron Reed的《Learning XNA 4.0》一书。我将相机游戏组件添加到我的项目中,但是这个相机的行为真的很奇怪。移动鼠标使它"跳跃",然后崩溃。我不知道是什么引起的。代码看起来和书上的几乎一模一样。它以前工作,但现在它不是,虽然我不记得我是否改变了什么(我想没有)。请注意,我只是在游戏中注册了这个组件,仅此而已。它应该起作用,但它没有。任何帮助都太好了。下面是代码:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace MyGame
{
public class Camera : Microsoft.Xna.Framework.GameComponent
{
public Matrix View { get; protected set; }
public Matrix Projection { get; protected set; }
public Vector3 CameraPosition { get; protected set; }
public Vector3 CameraDirection { get; protected set; }
public Vector3 CameraUp { get; protected set; }
private MouseState prevMouseState;
public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up)
: base(game)
{
// Some initialization of camera.
CameraPosition = pos;
CameraDirection = target - pos;
CameraDirection.Normalize();
CameraUp = up;
CreateLookAt();
Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.PiOver4,
(float)Game.Window.ClientBounds.Width /
(float)Game.Window.ClientBounds.Height,
1f, 3000f);
}
public override void Initialize()
{
// Set mouse position and do initial get state.
Mouse.SetPosition(Game.Window.ClientBounds.Width / 2,
Game.Window.ClientBounds.Height / 2);
prevMouseState = Mouse.GetState();
base.Initialize();
}
public override void Update(GameTime gameTime)
{
// Standard WSAD keyboard movement.
if (Keyboard.GetState().IsKeyDown(Keys.W))
CameraPosition += CameraDirection;
if (Keyboard.GetState().IsKeyDown(Keys.S))
CameraPosition -= CameraDirection;
if (Keyboard.GetState( ).IsKeyDown(Keys.A))
CameraPosition += Vector3.Cross(CameraUp, CameraDirection);
if (Keyboard.GetState().IsKeyDown(Keys.D))
CameraPosition -= Vector3.Cross(CameraUp, CameraDirection);
// Yaw rotation (via mouse).
CameraDirection = Vector3.Transform(CameraDirection,
Matrix.CreateFromAxisAngle(CameraUp, (-MathHelper.PiOver4 / 150) *
(Mouse.GetState().X - prevMouseState.X)
));
// Pitch rotation (via mouse).
CameraDirection = Vector3.Transform(CameraDirection,
Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection),
(MathHelper.PiOver4 / 100) *
(Mouse.GetState().Y - prevMouseState.Y)
));
CameraUp = Vector3.Transform(CameraUp,
Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection),
(MathHelper.PiOver4 / 100) *
(Mouse.GetState().Y - prevMouseState.Y)
));
prevMouseState = Mouse.GetState();
CreateLookAt();
base.Update(gameTime);
}
private void CreateLookAt()
{
View = Matrix.CreateLookAt(CameraPosition,
CameraPosition + CameraDirection, CameraUp);
}
}
}
谁能检查一下这个代码是否适用于他?任何想法都很棒!
//编辑1:在游戏初始化中,我使用以下代码:
Camera cam = new Camera(this, new Vector3(0, 0, 100), Vector3.Zero, Vector3.Up);
Components.Add(cam);
,然后绘制模型。我使用cam的视图和投影矩阵在模型的BasicEffect。
//编辑2:出了严重的问题。我做了一些调试,似乎在某些时候那些Vector3对象的X,Y,Z属性设置为NaN。我不知道怎么回事,什么时候。而且(也许这没什么)在运行了一段时间后,gameTime显示经过的游戏时间只有16毫秒(就像它跳过帧一样?)并且游戏运行缓慢。无论我什么时候调试,这16毫秒总是一样的。
是否有可能我搞砸了XNA/c#设置?如果是这样,有人能给我点提示吗?
// Pitch rotation (via mouse).
CameraDirection = Vector3.Transform(CameraDirection,
Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection),
(MathHelper.PiOver4 / 100) *
(Mouse.GetState().Y - prevMouseState.Y)
));
CameraUp = Vector3.Transform(CameraUp,
Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection),
(MathHelper.PiOver4 / 100) *
(Mouse.GetState().Y - prevMouseState.Y)
));
当你使用CreateFromAxisAngle时,第一个参数(轴)需要是单位长度的向量。如果它不是单位长度向量,它将导致一个扭曲的(倾斜的)矩阵和一个过度(或不足)旋转的矩阵。
当你交叉两个向量时,结果很少是一个单位长度的向量。得到一个横单位长度的结果。试试这个:
Vector3.Transform(CameraDirection, Matrix.CreateFromAxisAngle(Vector3.Normalize(Vector3.Cross(CameraUp, CameraDirection)), ...
通过添加"Normalize",它使交叉的结果成为单位长度向量。不要忘记对偏航线也做同样的处理。