在我开始之前:我尝试过gamedev.stackexchange,但是没有人回答,所以我认为我会在这里测试自己的运气:)
我是3D编程的新手,我正在尝试制作一款游戏,让玩家可以控制迷宫周围的角色。
我当前的问题不是真的使鼠标居中并读取它来旋转相机-尽管我希望将来,现在WASD运动也可以旋转,我想这意味着我需要旋转轴。我已经尝试了大约1-2个小时,环顾四周,有人说要使用四元数,而有人说要使用矩阵,但是到目前为止,我还没法做任何事情。为了澄清,当我按住W时,它会向前移动。但是,如果我然后旋转相机向右看并按住W,它将向相机的左侧移动<---如果可能,我想解决这个问题
我对如何做或如何做非常困惑,我会提供我的Camera类和Game1类,尽管我会警告您-我不太擅长将事情布置得很好。我不是一个经验丰富的程序员,所以要我将知识应用到我的项目中可能要花我一段时间才能做好,谢谢:D
public class Camera
{
float angle = 1f;
float currentAngle;
public Vector3 cameraPosition;
public Vector3 cameraTarget;
public Matrix worldMatrix { get; set; }
public Matrix viewMatrix { get; set; }
public Matrix projectionMatrix { get; set; }
public Matrix rotationMatrix;
Matrix playerPos;
Matrix movement;
Vector3 position;
public void SetMovement(Matrix inMovement)
{
movement = inMovement;
}
public void SetPosition(Vector3 inPosition)
{
position = inPosition;
}
public Camera(GraphicsDevice graphics, Vector3 inTarget)
{
rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(0f));
cameraTarget = new Vector3(0f, 0f, 0f);
cameraPosition = new Vector3(0f, -1f, 3.5f);
playerPos = Matrix.CreateScale(0.01f) *
Matrix.CreateTranslation(position);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f),
graphics.DisplayMode.AspectRatio,
0.03f, 100f);
worldMatrix = Matrix.CreateWorld(inTarget, Vector3.Forward, Vector3.Up);
viewMatrix = Matrix.CreateLookAt(position, inTarget, Vector3.Up);
}
public virtual void Update()
{
if(Keyboard.GetState().IsKeyDown(Keys.Right))
{
currentAngle += angle;
rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(currentAngle)) * rotationMatrix;
currentAngle = 0;
}
if (Keyboard.GetState().IsKeyDown(Keys.Left))
{
currentAngle += angle * -1;
rotationMatrix = rotationMatrix * Matrix.CreateRotationY(MathHelper.ToRadians(currentAngle));
currentAngle = 0;
}
viewMatrix = Matrix.CreateLookAt(new Vector3(cameraPosition.X + position.X, cameraPosition.Y + position.Y + 1.02f, //FIRST PERSON CAMERA
position.Z + 0.013f), cameraTarget + position + new Vector3(0f,1f,0f), Vector3.Up) * rotationMatrix;
//viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up); //MAP VIEW CAMERA
}
}
这是Game1
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Model map, player;
Camera playerCamera;
Vector3 playerPosition;
Matrix playerCurrentPosition, cameraCurrentPosition;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 1080;
graphics.PreferredBackBufferWidth = 1920;
}
protected override void Initialize()
{
player = Content.Load<Model>("ball2");
playerPosition = new Vector3(-0.84f, 0.86f, 0.02f);
playerCamera = new Camera(GraphicsDevice, new Vector3(0f, 0f, 0f));
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
map = Content.Load<Model>("newMap");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
playerCamera.SetMovement(playerCurrentPosition);
playerCamera.SetPosition(playerPosition);
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if (Keyboard.GetState().IsKeyDown(Keys.W))
playerPosition.Y += 0.01f;
if (Keyboard.GetState().IsKeyDown(Keys.A))
playerPosition.X -= 0.003f;
if (Keyboard.GetState().IsKeyDown(Keys.S))
playerPosition.Y -= 0.003f;
if (Keyboard.GetState().IsKeyDown(Keys.D))
playerPosition.X += 0.003f;
playerCurrentPosition =
Matrix.CreateScale(0.01f) *
Matrix.CreateTranslation(playerPosition);
cameraCurrentPosition = Matrix.CreateTranslation(playerPosition - new Vector3(0f, 0.1f, 0f));
playerCamera.Update();
base.Update(gameTime);
}
public void DrawModel(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.View = view;
effect.Projection = projection;
effect.World = world;
effect.EnableDefaultLighting();
}
mesh.Draw();
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Crimson);
DrawModel(map, playerCamera.worldMatrix, playerCamera.viewMatrix, playerCamera.projectionMatrix);
DrawModel(player, playerCamera.worldMatrix * playerCurrentPosition, playerCamera.viewMatrix, playerCamera.projectionMatrix);
base.Draw(gameTime);
}
}
答案 0 :(得分:0)
显然有不同的方法,所以这可能不是最优雅的方法:
让我们假设您将相机旋转角度存储为角度rotationY
(您将需要第二角度,但这可能不会影响步行方向)。
我假设您当前有一些这样的代码:
if (kbState.IsKeyDown(Keys.W))
position += new Vector3(1, 0, 0) * elapsedTime;
我们现在要做的是旋转方向矢量,其旋转量与旋转相机的旋转量相同。我们可以为此使用矩阵变换(用sin和cos编写旋转会更快,但是由于每帧只运行一次,因此不必担心):
Matrix rotation = Matrix.CreateRotationY(rotationY);
Vector3 forward = Vector3.Transform(new Vector3(1, 0, 0), rotation);
if (kbState.IsKeyDown(Keys.W))
position += forward * elapsedTime;
基本上就是这样。对于向后运动,请使用-forward;对于横向运动,请使用相同的矩阵旋转第二个矢量。
执行此操作的方法有多种:您可以从相机的角度计算向前和向后的矢量(我认为从视图矩阵中获取它们非常快)。这可能会更快,但是再一次,这里的性能应该没什么太大的。