C# 奇怪的第一人称相机旋转XNA
我正在尝试在XNA4.0中创建第一人称视图摄影机。我让相机工作,我的场景渲染得很好。我的W、A、S、D动作也很好,但我不明白为什么我的鼠标旋转会出错 当我试着用相机向上看的时候,它会倾斜我的整个世界,向左和向右看都是一样的,都朝着同一个方向看。最终,我的整个世界翻转过来:SC# 奇怪的第一人称相机旋转XNA,c#,xna,camera,rotational-matrices,C#,Xna,Camera,Rotational Matrices,我正在尝试在XNA4.0中创建第一人称视图摄影机。我让相机工作,我的场景渲染得很好。我的W、A、S、D动作也很好,但我不明白为什么我的鼠标旋转会出错 当我试着用相机向上看的时候,它会倾斜我的整个世界,向左和向右看都是一样的,都朝着同一个方向看。最终,我的整个世界翻转过来:S using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsof
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace Brandon
{
public class FPC : GameComponent
{
private KeyboardState OldKeyboardState;
private MouseState OldMouseState;
private Vector3 Target = Vector3.Zero;
private Vector3 UpVector = Vector3.Up;
private Vector3 Position = new Vector3(0.0f, 0.0f, 1.0f);
private Vector2 Velocity = Vector2.Zero;
private Matrix View = Matrix.Identity;
private Matrix Projection = Matrix.Identity;
private BasicEffect Effects = null;
private float Speed = 5.0f;
private float WalkingSpeed = 1.0f;
private float RotationSpeed = 0.1f;
private float AngleX = 0.0f;
private float AngleY = 0.0f;
public BasicEffect Effect
{
get { return this.Effects; }
}
public FPC(Game game) : base(game)
{
Mouse.SetPosition(Game.GraphicsDevice.Viewport.Width / 2, Game.GraphicsDevice.Viewport.Height / 2);
Game.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
this.Effects = new BasicEffect(Game.GraphicsDevice);
this.OldMouseState = Mouse.GetState();
}
public override void Initialize()
{
base.Initialize();
}
public void LookAt(float FOV_Degrees, float NearPlaneDistance, float FarPlaneDistance, Vector3 Position, Vector3 Target, Vector3 UpVector)
{
this.Position = Position;
this.Target = Target;
this.UpVector = UpVector;
this.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(FOV_Degrees), Game.GraphicsDevice.Viewport.AspectRatio, NearPlaneDistance, FarPlaneDistance);
this.View = Matrix.CreateLookAt(Position, Target, UpVector);
}
private void UpdateView(Matrix rotationMatrix)
{
Vector3 finalTarget = this.Position + Vector3.Transform(this.Target, rotationMatrix);
Vector3 finalUp = Vector3.Transform(this.UpVector, rotationMatrix);
this.View = Matrix.CreateLookAt(this.Position, finalTarget, finalUp);
}
private void ProcessInput(GameTime gameTime)
{
bool isWalking = false;
KeyboardState CurrentKeyboardState = Keyboard.GetState();
Vector3 pos = Vector3.Zero;
if (CurrentKeyboardState.IsKeyDown(Keys.W)) pos.Z -= 1.0f;
if (CurrentKeyboardState.IsKeyDown(Keys.S)) pos.Z += 1.0f;
if (CurrentKeyboardState.IsKeyDown(Keys.A)) pos.X -= 1.0f;
if (CurrentKeyboardState.IsKeyDown(Keys.D)) pos.X += 1.0f;
if (CurrentKeyboardState.IsKeyDown(Keys.LeftShift)) isWalking = true;
this.OldKeyboardState = CurrentKeyboardState;
if (pos != Vector3.Zero)
{
pos.Normalize(); //So we don't move faster diagonally
pos *= (float)gameTime.ElapsedGameTime.TotalSeconds * (isWalking ? this.WalkingSpeed : this.Speed); //Smooth movement
}
this.ProcessMouseInput(gameTime);
Matrix rotationMatrix = Matrix.CreateRotationX(this.AngleX) * Matrix.CreateRotationY(this.AngleY);
this.Position += (isWalking ? this.WalkingSpeed : this.Speed) * Vector3.Transform(pos, rotationMatrix);
this.UpdateView(rotationMatrix);
}
//Rotate the camera using the mouse.
private void ProcessMouseInput(GameTime gameTime)
{
float amount = (float)gameTime.ElapsedGameTime.TotalSeconds;
MouseState mouse = Mouse.GetState();
if (mouse != this.OldMouseState)
{
int xDist = mouse.X - (Game.GraphicsDevice.Viewport.Width / 2);
int yDist = mouse.Y - (Game.GraphicsDevice.Viewport.Height / 2);
this.AngleX -= RotationSpeed * xDist * amount;
this.AngleY -= RotationSpeed * yDist * amount;
}
Mouse.SetPosition(Game.GraphicsDevice.Viewport.Width / 2, Game.GraphicsDevice.Viewport.Height / 2);
this.OldMouseState = mouse;
}
//Return a matrix for use with rendering hands holding weapons.
public Matrix ModelWorldMatrix(float xOffset, float yOffset, float zOffset, float scale)
{
Vector3 ModelPos = this.Position;
ModelPos += this.Target * zOffset;
ModelPos += Vector3.UnitY * yOffset;
ModelPos += Vector3.UnitX * xOffset;
return Matrix.CreateScale(scale) * Matrix.CreateRotationX(MathHelper.ToRadians(this.AngleX)) * Matrix.CreateRotationY(MathHelper.ToRadians(this.AngleY)) * Matrix.CreateTranslation(ModelPos);
}
public override void Update(GameTime gameTime)
{
ProcessInput(gameTime);
this.Effects.View = View;
this.Effects.Projection = Projection;
this.Effects.World = Matrix.Identity;
base.Update(gameTime);
}
}
}
我已经尝试了各种各样的示例代码,并遵循了我能找到的所有教程,但没有一个具有与我相同的问题。它们要么不工作,要么落后很多
你知道我做错了什么吗?你将
这个目标初始化为0,0,0。这个值永远不会改变
然后在随后的UpdateView
方法中,通过将this.Target
转换为仅表示旋转的矩阵来计算finalTarget
结果
Vector3.Transform(this.Target,rotationMatrix)
本质上与
Vector3.Transform(Vector3.Zero,旋转矩阵)
重要的是,这总是会导致(0,0,0),它应该将finalTarget
放在与this.position
相同的位置,但浮点错误除外,浮点错误会给每个组件提供非常小的值,这会导致您的问题
开始时,请尝试为this.Target指定值0,0,-1(这会导致初始外观方向与当前代码尝试执行的方向相同,但会提供要处理的向量3.Transform()
),您应该可以