I've been looking around for a tutorial on how to do this properly and Google keeps coming up empty. Maybe this is a really simple subject, but I'm not sure what to do.
What I've found so far gives me code that looks like this:
if (currentKeyboardState.IsKeyDown(Keys.A))
{
RotationAngle += 0.01f;
float circle = MathHelper.Pi * 2;
RotationAngle = RotationAngle % circle;
}
Only, this doesn't do much. It came from MSDN. That was the best-looking solution I could find.
All I want to do is allow the player to spin their ship around and shoot in another direction.
I'm making a game that bears a fair resemblance to asteroids, but I can only shoot in one direction at the moment.
Any help would be appreciated :)
Edit: This is my current Player.cs:
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace GameTest
{
class Player
{
public Texture2D PlayerTexture;
public Vector2 Position;
public bool Alive;
public int Health;
public Vector2 origin;
public float RotationAngle;
KeyboardState currentKeyboardState;
KeyboardState previousKeyboardState;
public int Width
{
get { return PlayerTexture.Width; }
}
public int Height
{
get { return PlayerTexture.Height; }
}
public void Initialize(Texture2D texture, Vector2 position)
{
PlayerTexture = texture;
Position = position;
Alive = true;
Health = 10;
origin.X = PlayerTexture.Width / 2;
origin.Y = PlayerTexture.Height / 2;
}
public void Update(GameTime gameTime)
{
RotationAngle += 10f;
previousKeyboardState = currentKeyboardState;
currentKeyboardState = Keyboard.GetState();
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
if (currentKeyboardState.IsKeyDown(Keys.A))
{
//float circle = MathHelper.Pi * 2;
//RotationAngle = RotationAngle % circle;
}
if (currentKeyboardState.IsKeyDown(Keys.D))
{
//rotation
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(PlayerTexture, Position, null, Color.White, RotationAngle, origin, 1f, SpriteEffects.None, 0f);
}
}
}
My guess is you are missing the 'origin', or the center of rotation:
RotationAngle += .5f;
float circle = MathHelper.Pi * 2;
RotationAngle = RotationAngle % circle;
Vector2 origin = new Vector2(texture.Width / 2, texure.Height / 2);
spriteBatch.Draw(texture, position, null, Color.White, RotationAngle, origin, 1.0f, SpriteEffects.None, 0f);
As for the angle you want to shoot at, you'll need some geometry (something like this, not tested... but if I remember correctly):
Vector2 velocity = new Vector2(speed*Math.Cos(RotationAngle), speed*Math.Sin(RotationAngle));
Also, use the debugger to make sure that the rotation angle is properly changing.
Related
Im trying to write some simple 2d physics in monogame.
I release a ball from a given start position with a given velocity and I want it to bounce back up when it is colliding with the floor.
My problem is that I seem to give the ball more energi for each bounce i.e. it bounces higher and higher for each collision with the floor. It should be the other way around.
I have:
float get_VelocityX(float _speed, double _angle)
{
return velocity_x = velocity_x +_speed * (float)Math.Cos(_angle);
}
public float get_VelocityY(float _speed, double _angle, float _t, float gravity)
{
return velocity_y = velocity_y + _speed * (float)Math.Cos(_angle); // - (float)(-gravity * _t);
}
And in my Update function I have this:
if (speed > 0)
{
timeCount += (float)gameTime.ElapsedGameTime.TotalSeconds;
t += timeCount;
}
else
{
return;
}
Vx = ball.get_VelocityX(speed, angle);
Vy = ball.get_VelocityY(speed, angle, t, gravity);
if (posX >= windowMAX)
{
posX = posX + -Vx * friction * t;
}
if (posY > windowMIN)
{
posY = posY + -Vy * friction * t;
}
else
{
posY += gravity;
}
ballRect.X = (int)posX;
ballRect.Y = (int)posY;
Where posX, posY and speed are user inputs for start position and velocity.
Gravity is just a float = 9.82f;
Right now Im not doing anything with the posX except setting the balls starting position. Next step will be to implement a throwing motion.
EDIT:
Friction = 0.001f;
t is deltatime.
I went through your logic and have prepared a sample code. Please read the following before you go through it.
In order to simulate real-life motion, you need to implement the physics accurately. Although your implemented velocity and position seems mostly correct, the gravity needs to be treated as acceleration, and therefore adding its value to the position (as done in your code) is incorrect. I assume that this is the reason why you aren't getting your expected result since the value of increment on the Y-component of position is far greater than it should be.
Instead of keeping PosX, PosY for the position, Velocity_X..(), Velocity_Y..() for velocity, I would advise you to use struct Vector2 as shown below in my code, which is included in the Monogame framework and has a lot more helping functions built-in. This will help in making your code shorter and cleaner.
I did not understand why you used the Cosine of the given angle in your implementation of Velocity for both its X and Y components. My code below is ignoring this.
You can see my code below. Here the bouncing object Box is of the type struct PhyObj with all the needed Physics of motion implemented within it.
public class Game1 : Game
{
private SpriteBatch _batch;
internal Texture2D Texture;
public static Vector2 GravityAcceleration => new Vector2(0, 9.8f);//Constant accerleration along Y-Axis
internal Rectangle Ground;
internal PhyObj Box;
public Game1()
{
_ = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void LoadContent()
{
Point center = Window.ClientBounds.Center;
Box = new PhyObj(new Vector2(center.X, 0), Vector2.Zero, 30, 30);
Ground = new Rectangle(0, center.Y, center.X * 2, 10);
_batch = new SpriteBatch(GraphicsDevice);
Texture = new Texture2D(GraphicsDevice, 1, 1);
Texture.SetData(new[] { Color.White });
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
Box.Accelerate(GravityAcceleration, gameTime);
if (Box.Pos.Y > Ground.Top - Box.Dest.Height)//Check if bounce needed
{
Box.Pos.Y = Ground.Top - Box.Dest.Height;//Clipping
Box.Vel.Y *= -1; //Bouncing
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
_batch.Begin();
_batch.Draw(Texture, Ground, Color.Black);
_batch.Draw(Texture, Box.Dest, Color.White);
_batch.End();
base.Draw(gameTime);
}
}
public struct PhyObj
{
internal static float friction => 0.005f;
public PhyObj(Vector2 x, Vector2 v, int width, int height)
{
Pos = x;
Vel = v;
Dest = new Rectangle(0, 0, width, height);
(Dest.X, Dest.Y) = ((int)Pos.X, (int)Pos.Y);
}
internal Vector2 Pos, Vel;
internal Rectangle Dest;
public void Accelerate(Vector2 acc, GameTime time)
{
Vel += acc - Vel * friction;
Pos += Vel * (float)time.ElapsedGameTime.TotalSeconds;
(Dest.X, Dest.Y) = ((int)Pos.X, (int)Pos.Y);
}
}
As shown in the Update() function, the PhyObj Box is being accelerated externally (In this case gravity, but you can add your custom external force), and the velocity/position it needs to attain is calculated internally.
The bouncing logic is simple: The Y-component of velocity is inverted.
The "Clipping" process here makes sure that the Box does not cross the Ground object even when the downward acceleration is acting upon it.
The next subsequent bounces have their height reduced due to the friction value (Done internally by the struct PhyObj).
Before I start: I tried gamedev.stackexchange and nobody replied so I thought I'd test my luck here :)
I'm relatively new to 3D programming and I'm trying to make a game where the player can control a character around a maze.
My current problem isn't really getting the mouse to be centre and reading it to rotate the camera - although I'd like to in the future, right now it's getting the WASD movement to also rotate, I assume this means I'd need to rotate the axis. I've been trying for about 1-2 hours looking around, some say to use Quaternions and others Matrices, but I haven't been able to get anything to work so far. To clarify, when I hold W, it moves forward. But if I then rotate the camera to look to the right and hold W, it'll move left of the camera <--- I want to fix this if possible
I'm very lost at what to do or how best to do it, I'll provide my Camera class and Game1 class, although I'll warn you - I'm not very good at laying things out nicely. I'm not a highly experiences programmer so asking me to apply knowledge to my project may take me a while to get right, thanks :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
}
}
Here's 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);
}
}
There are obviously different approaches to this, so this might not be the most elegant:
Let's assume that you store your camera rotation as an angle rotationY (you will need a second angle, but that probably won't influence the walking direction).
I assume that you currently have some code like this:
if (kbState.IsKeyDown(Keys.W))
position += new Vector3(1, 0, 0) * elapsedTime;
What we now want to do is rotate that direction vector the same amount we rotated the camera. We can use Matrix transformations for that (writing the rotation with sin and cos would be faster, but as this only runs once per frame, that should not be a major concern):
Matrix rotation = Matrix.CreateRotationY(rotationY);
Vector3 forward = Vector3.Transform(new Vector3(1, 0, 0), rotation);
if (kbState.IsKeyDown(Keys.W))
position += forward * elapsedTime;
That's basically it. For backward movement, use -forward and for sideways motion, rotate a second vector using the same matrix.
There are different ways of doing this: You can compute the forward and sideways vector from the camera's point of view (I think it is quite fast to get them from the view matrix). That will probably be faster, but once again, performance shouldn't matter too much here.
So I'm implementing shooting in my game, but when I resize the window or move (because of my camera) the mouse position gets offset and the shots obviously don't hit where I want them to, and I don't know how to fix it. Here's the relevant code:
Shot.cs
public class Shot : Sprite {
private float Speed = 500;
private Vector2 Dir;
private Vector2 Velocity;
public Shot(Texture2D texture, Vector2 position)
: base(texture) {
this.Position = position;
this.Dir = Input.GetMousePos() - Position;
}
void Start() {
}
public void Update(GameTime gameTime) {
var delta = (float)gameTime.ElapsedGameTime.TotalSeconds;
Dir.Normalize();
Velocity = Dir * Speed;
Position += Velocity * delta;
}
}
Camera.cs GetTransform() (please note that I didn't write this)
public Matrix GetTransform(GraphicsDevice graphicsDevice) {
transform = Matrix.CreateTranslation(new Vector3(-Position.X, -Position.Y, 0)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(graphicsDevice.Viewport.Width * 0.5f, graphicsDevice.Viewport.Height * 0.5f, 1));
return transform;
}
spriteBatch.Begin();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null, null, camera.GetTransform(GraphicsDevice));
Also wanted to add that this isn't a shooting specific problem, the position also gets offset when I try to drag a GUI window, so I think I need to do modify my GetMousePosition method, but I'm not sure how.
EDIT: Here's GetMousePos()
public static Vector2 GetMousePos() {
return new Vector2(mouseState.X, mouseState.Y);
}
I have a sprite called Tool that moves with a speed represented as a float and in a direction represented as a Vector2. When I click the mouse on the screen the sprite change its direction and starts to move towards the mouseclick. In addition to that I rotate the sprite so that it is facing in the direction it is heading. However, when I add a camera that is suppose to follow the sprite so that the sprite is always centered on the screen, the sprite won't move in the given direction and the rotation isn't accurate anymore. This only happens when I add the Camera.View in the spriteBatch.Begin(). I was hoping anyone could maybe shed a light on what I am missing in my code, that would be highly appreciated.
Here is the camera class i use:
public class Camera
{
private const float zoomUpperLimit = 1.5f;
private const float zoomLowerLimit = 0.1f;
private float _zoom;
private Vector2 _pos;
private int ViewportWidth, ViewportHeight;
#region Properties
public float Zoom
{
get { return _zoom; }
set
{
_zoom = value;
if (_zoom < zoomLowerLimit)
_zoom = zoomLowerLimit;
if (_zoom > zoomUpperLimit)
_zoom = zoomUpperLimit;
}
}
public Rectangle Viewport
{
get
{
int width = (int)((ViewportWidth / _zoom));
int height = (int)((ViewportHeight / _zoom));
return new Rectangle((int)(_pos.X - width / 2), (int)(_pos.Y - height / 2), width, height);
}
}
public void Move(Vector2 amount)
{
_pos += amount;
}
public Vector2 Position
{
get { return _pos; }
set { _pos = value; }
}
public Matrix View
{
get
{
return Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(ViewportWidth * 0.5f, ViewportHeight * 0.5f, 0));
}
}
#endregion
public Camera(Viewport viewport, float initialZoom)
{
_zoom = initialZoom;
_pos = Vector2.Zero;
ViewportWidth = viewport.Width;
ViewportHeight = viewport.Height;
}
}
And here is my Update and Draw-method:
protected override void Update (GameTime gameTime)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
TouchCollection touchCollection = TouchPanel.GetState ();
foreach (TouchLocation tl in touchCollection) {
if (tl.State == TouchLocationState.Pressed || tl.State == TouchLocationState.Moved) {
//direction the tool shall move towards
direction = touchCollection [0].Position - toolPos;
if (direction != Vector2.Zero) {
direction.Normalize ();
}
//change the direction the tool is moving and find the rotationangle the texture must rotate to point in given direction
toolPos += (direction * speed * elapsed);
RotationAngle = (float)Math.Atan2 (direction.Y, direction.X);
}
}
if (direction != Vector2.Zero) {
direction.Normalize ();
}
//move tool in given direction
toolPos += (direction * speed * elapsed);
//change cameracentre to the tools position
Camera.Position = toolPos;
base.Update (gameTime);
}
protected override void Draw (GameTime gameTime)
{
graphics.GraphicsDevice.Clear (Color.Blue);
spriteBatch.Begin (SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, Camera.View);
spriteBatch.Draw (tool, new Vector2 (toolPos.X, toolPos.Y), null, Color.White, RotationAngle, originOfToolTexture, 1, SpriteEffects.None, 1);
spriteBatch.End ();
base.Draw (gameTime);
}
You need to convert your cursor position into world position:
Vector2 adjustedPosition = Vector2.Transform(touchCollection[0].Position, Matrix.Invert(camera.View));
Then your direction would be:
direction = adjustedPosition - toolPos;
I'm trying to create an First Person View camera in XNA 4.0. I got the camera working and my scene renders fine. My movement with the W, A, S, D works fine as well but I cannot figure out why my Mouse rotations are messed up.
When I try to look Up with the camera, it tilts my entire world and looking Left & Right does the same thing and both look in the same direction. Eventually, my entire world flips :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);
}
}
}
I've tried all sorts of sample code and followed all tutorials I could find but none of them have the same problems I have. They either don't work or they lag a ton!
Any ideas what I'm doing wrong?
You initialize this.Target to 0,0,0. This value never changes.
then later in your UpdateView method, you calculate finalTarget by transforming this.Target by a matrix representing a rotation only.
The result of
Vector3.Transform(this.Target, rotationMatrix) is essentially the same as
Vector3.Transform(Vector3.Zero, rotationMatrix).
Essentialy, that always results in (0,0,0) which should place finalTarget at the same position as this.Position except for floating point error that will give very small values to each component which factor in to cause your issue.
Try starting off by giving this.Target the value of 0,0,-1 (which causes the initial look direction to be the same as what your current code is trying to do, but gives the Vector3.Transform() something to work with) and you should be ok.