C# 奇怪的第一人称相机旋转XNA

C# 奇怪的第一人称相机旋转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

我正在尝试在XNA4.0中创建第一人称视图摄影机。我让相机工作,我的场景渲染得很好。我的W、A、S、D动作也很好,但我不明白为什么我的鼠标旋转会出错

当我试着用相机向上看的时候,它会倾斜我的整个世界,向左和向右看都是一样的,都朝着同一个方向看。最终,我的整个世界翻转过来:S

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()
),您应该可以