我有3个类:游戏类,相机类和模型类。该项目建立并运行, 模型出现,当我按下W并使其前进时相机跟随它,但当我重新启动项目并旋转模型以面对任何其他方式它似乎做一个鼻子潜水,而不是直接,我试图实现是一个遵循模型的相机,
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 test1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
//Visual components
Ship ship = new Ship();
Camera _camera;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// this.graphics.ToggleFullScreen();
this._camera = new Camera(graphics.GraphicsDevice.Viewport);
this._camera.LookAt = new Vector3(0.0f, 0.0f, 0.0f);
this._camera.Position = new Vector3(0.0f, -5000.0f, 1000.0f);
base.Initialize();
}
protected override void LoadContent()
{
ship.Model = Content.Load<Model>("Models/p1_wedge");
ship.Transforms = _camera.SetupEffectDefaults(ship.Model);
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
// Get some input.
UpdateInput();
base.Update(gameTime);
}
protected void UpdateInput()
{
// Get the game pad state.
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
KeyboardState currentKeyState = Keyboard.GetState();
ship.Update(currentState);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
//camera
this._camera.Update();
_camera.LookAt = ship.Position;
Matrix shipTransformMatrix = ship.RotationMatrix
* Matrix.CreateTranslation(ship.Position);
DrawModel(ship.Model, shipTransformMatrix, ship.Transforms);
base.Draw(gameTime);
}
public void DrawModel(Model model, Matrix modelTransform,
Matrix[] absoluteBoneTransforms)
{
//Draw the model, a model can have multiple meshes, so loop
foreach (ModelMesh mesh in model.Meshes)
{
//This is where the mesh orientation is set
foreach (BasicEffect effect in mesh.Effects)
{
effect.World =
absoluteBoneTransforms[mesh.ParentBone.Index] *
modelTransform;
effect.Projection = _camera.ProjectionMatrix;
effect.View = _camera.ViewMatrix;
}
//Draw the mesh, will use the effects set above.
mesh.Draw();
}
}
}
}
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 test1
{
public class Camera
{
private Vector3 _position;
private Vector3 _lookAt;
private Matrix _viewMatrix;
private Matrix _projectionMatrix;
private float _aspectRatio;
public Camera(Viewport viewport)
{
this._aspectRatio = ((float)viewport.Width) / ((float)viewport.Height);
this._projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(40.0f),
this._aspectRatio,
1.0f,
10000.0f);
}
public Matrix[] SetupEffectDefaults(Model myModel)
{
Matrix[] absoluteTransforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(absoluteTransforms);
foreach (ModelMesh mesh in myModel.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.Projection = ProjectionMatrix;
effect.View = ViewMatrix;
}
}
return absoluteTransforms;
}
public Vector3 Position
{
get { return this._position; }
set { this._position = value; }
}
public Vector3 LookAt //= Vector3.Zero;
{
get { return this._lookAt; }
set { this._lookAt = value; }
}
public Matrix ViewMatrix
{
get { return this._viewMatrix; }
}
public Matrix ProjectionMatrix
{
get { return this._projectionMatrix; }
}
public void Update()
{
this._viewMatrix =
Matrix.CreateLookAt(this._position, this._lookAt, Vector3.Up);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace test1
{
class Ship
{
public Model Model;
public Matrix[] Transforms;
//Position of the model in world space
public Vector3 Position = Vector3.Zero;
//Velocity of the model, applied each frame to the model's position
public Vector3 Velocity = Vector3.Zero;
private const float VelocityScale = 5.0f;
public Matrix RotationMatrix =
Matrix.CreateRotationX(MathHelper.PiOver2);
private float rotation;
public float Rotation
{
get { return rotation; }
set
{
float newVal = value;
while (newVal >= MathHelper.TwoPi)
{
newVal -= MathHelper.TwoPi;
}
while (newVal < 0)
{
newVal += MathHelper.TwoPi;
}
if (rotation != value)
{
rotation = value;
RotationMatrix =
Matrix.CreateRotationX(MathHelper.PiOver2) *
Matrix.CreateRotationZ(rotation);
}
}
}
public void Update(GamePadState controllerState)
{
KeyboardState currentKeyState = Keyboard.GetState();
if (currentKeyState.IsKeyDown(Keys.A))
Rotation += 0.10f;
else
// Rotate the model using the left thumbstick, and scale it down.
Rotation -= controllerState.ThumbSticks.Left.X * 0.10f;
if (currentKeyState.IsKeyDown(Keys.D))
Rotation -= 0.10f;
if (currentKeyState.IsKeyDown(Keys.W))
Velocity += RotationMatrix.Forward * VelocityScale;
else
// Finally, add this vector to our velocity.
Velocity += RotationMatrix.Forward * VelocityScale *
controllerState.Triggers.Right;
// In case you get lost, press A to warp back to the center.
if (currentKeyState.IsKeyDown(Keys.Enter))
{
Position = Vector3.Zero;
Velocity = Vector3.Zero;
Rotation = 0.0f;
}
Position += Velocity;
Velocity *= 0.95f;
}
}
}
答案 0 :(得分:1)
我这样做:
我在平面上展示它以便于理解,但不需要进行计算。
您只需要摄像机的前向矢量,船舶的前向矢量,相机到船舶的距离以及摄像机的高程矢量。
这种方式当船舶移动时会做类似的事情:
Camera.Forward = Vector3.Lerp( Ship.Forward, Camera.Fordward, 0.05f);
Camera.Forward.Normalize();
Camera.Forward*=Camera.Distance;
Camera.Target = Ship.Target;
Camera.Source = Ship.Target - Camera.Forward;
Camera.Position = Camera.Source + Camera.Elevation;
我希望这会有用。