Camera is stuttering after random amount of time

Hello everyone,

I have a problem that my camera starts to stutter when moving it after a random amount of time. This is not the case for the movement itself. That runs really smoothly. It is just hte camera that starts to stutter. Small notice I am working in monogame

Here is the code of the main

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Cube_chaser
{ 
    public class CubeChaserGame : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Camera camera;
        Map map;
        BasicEffect effect;
    
    private Vector2 mouseRotationBuffer;
    private MouseState currentMouseState, previousMouseState;
    public Vector3 moveVector = Vector3.Zero;


    public CubeChaserGame()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

    }

    protected override void Initialize()
    {
        camera = new Camera(this, new Vector3(0.5f, 0.5f, 0.5f), Vector3.Zero, 5f);
        Components.Add(camera);
        effect = new BasicEffect(GraphicsDevice);
        map = new Map(GraphicsDevice);
        IsMouseVisible = false;
        graphics.IsFullScreen = true;
        previousMouseState = Mouse.GetState();
        base.Initialize();

    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
    }

    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();
        float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

        KeyboardState keyState = Keyboard.GetState();
        currentMouseState = Mouse.GetState();
        moveVector = Vector3.Zero;


        //Handle the mouse movement for rotation

        float deltaX, deltaY;

        if (currentMouseState != previousMouseState)
        {
            //We need to save the mouse location for further use
            deltaX = (currentMouseState.X - (GraphicsDevice.Viewport.Width / 2));
            deltaY = (currentMouseState.Y - (GraphicsDevice.Viewport.Height / 2));

            mouseRotationBuffer.X -= (0.09f * deltaX * dt);
            mouseRotationBuffer.Y -= (0.09f * deltaY * dt);

            if (mouseRotationBuffer.Y < MathHelper.ToRadians(-75.0f))
            {
                mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(-75.0f));
            }

            if (mouseRotationBuffer.Y > MathHelper.ToRadians(75.0f))
            {
                mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(75.0f));
            }

            camera.Rotation = new Vector3(-MathHelper.Clamp(mouseRotationBuffer.Y, MathHelper.ToRadians(-75.0f), MathHelper.ToRadians(75.0f)), MathHelper.WrapAngle(mouseRotationBuffer.X), 0);

            deltaX = 0;
            deltaY = 0;
        }

        try { Mouse.SetPosition(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2); }
        catch { }

        if (keyState.IsKeyDown(Keys.W)) moveVector.Z = 1;
        if (keyState.IsKeyDown(Keys.S)) moveVector.Z = -1;
        if (keyState.IsKeyDown(Keys.A)) moveVector.X = 1;
        if (keyState.IsKeyDown(Keys.D)) moveVector.X = -1;
        if (keyState.IsKeyDown(Keys.Space) && camera.Position.Y >= 0.5f && camera.Position.Y <= 0.8f) moveVector.Y = 0.05f;
        // if (camera.Position.Y == 0.8f&&camera.Position.Y>=0.5f)camera.moveVector.Y=-0.01f;
        if (moveVector != Vector3.Zero)
        {
            //We don't want to make the player move faster when it is going diagonally.
            moveVector.Normalize();
            //Now we add the smoothing factor and speed factor
            moveVector *= (dt * camera.cameraSpeed);

            Vector3 newPosition = camera.PreviewMove(moveVector);

            bool moveTrue = true;

            if (newPosition.X < 0 || newPosition.X > Map.mazeWidth) moveTrue = false;
            if (newPosition.Z < 0 || newPosition.Z > Map.mazeHeight) moveTrue = false;
            foreach (BoundingBox boxes in map.GetBoundsForCell((int)newPosition.X, (int)newPosition.Z))
            {
                if (boxes.Contains(newPosition) == ContainmentType.Contains)
                {
                    moveTrue = false;
                }
            }

            if (moveTrue) camera.Move(moveVector);
            previousMouseState = currentMouseState;
            camera.Update(gameTime);
            base.Update(gameTime);
        }
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);
        map.Draw(camera, effect);
        // TODO: Add your drawing code here

        base.Draw(gameTime);
    }
}
}

This is the code for the camera:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

namespace Cube_chaser
{
    public class Camera: GameComponent
    {
        #region Fields
        public Vector3 cameraPosition;
        public Vector3 cameraRotation;
        public float cameraSpeed;
        private Vector3 cameraLookAt;
        


        #endregion
    #region Properties
    public Matrix Projection
    {
        get;
        protected set;
    }       

    public Matrix View
    {
        get
        {
            return Matrix.CreateLookAt(cameraPosition, cameraLookAt, Vector3.Up);
        }
    }

    public Vector3 Position
    {
        get { return cameraPosition; }
        set
        {
            cameraPosition = value;
            UpdateLookAt();
        }
    }

    public Vector3 Rotation
    {
        get { return cameraRotation; }
        set
        {
            cameraRotation = value;
            UpdateLookAt();
        }
    }
   
    #endregion

    #region Constructor
    public Camera (Game game, Vector3 position, Vector3 rotation, float speed):base(game)
    {
        
        cameraSpeed = speed;
        
        //Setup the projection Matrix
        Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.AspectRatio, 0.05f, 100.0f);

        MoveTo(position, rotation);

        
    }

    #endregion

    #region Helper Methods
    //Set the camera its position and rotation
    public void MoveTo(Vector3 pos, Vector3 rot)
    {
        Position = pos;
        Rotation = rot;

    }

    //Updating the look at vector
    public void UpdateLookAt()
    {
        //Built a rotation matrix to rotate the direction we are looking
        Matrix rotationMatrix = Matrix.CreateRotationX(cameraRotation.X) * Matrix.CreateRotationY(cameraRotation.Y);

        // Build a look at offset vector 
        Vector3 lookAtOffset = Vector3.Transform(Vector3.UnitZ, rotationMatrix);

        //Update our camera's look at the vector
        cameraLookAt = (cameraPosition + lookAtOffset);

    }


    //Method to create movement and to check if it can move:)
    public Vector3 PreviewMove(Vector3 amount)
    {
        //Create a rotation matrix to move the camera
        Matrix rotate = Matrix.CreateRotationY(cameraRotation.Y);

        //Create the vector for movement
        Vector3 movement = new Vector3(amount.X, amount.Y, amount.Z);
        movement = Vector3.Transform(movement, rotate);

        // Give the value of the camera position +ze movement
        return (cameraPosition+movement);
    }

    //Method that moves the camera when it hasnt'collided with anything
    public void Move(Vector3 scale)
    {
        //Moveto the location
        MoveTo(PreviewMove(scale), Rotation);
    }

    #endregion

    /*public void Update(GameTime gameTime)
    {
        
    }*/
}
}

Any idea why the camera stutters after a while?
Thanks,

Jeromer

I was suffering from a similar problem a while ago in my project, and I found that the problem in my case was setting the position of the mouse using mouse.setposition at a very high rate. I am not sure if that will help, but you can see the thread here: Problems with Mouse.SetPosition

Basically, the problem was that I was using a variable timestep in my project, which made the mouse refresh at the center of the screen at a ridiculously high rate, and that in turn caused the camera to stutter.

Thanks ill try it. THought it does indeed look like the update just puts the mouse there rather often indeed.

Sure.

Just to let you know - although using fixed timestep solved the problem in my case, and I am alright with using that solution for now, overall this problably isn’t the best way to handle this problem.

All I know is that you probably need to limit the amount of times the mouse.setposition function is called any given second. Without that, the program will basically execute the function as frequently as your machine allows for it.

Yeah, thanks again man. You really helped me out a lot:)

And i’ll look for a better/different fix, and i’ll mention it.

Once again appreciate it, and ill update the tittle of the post.

This looks algorithmic to me.

Even if your mouse has zero jitter, some peoples will.

You shoulld probably wrap your code that triggers camera rotation to require the mouse delta x + y to sum to atleast a minimum thresh-hold amount. Before you allow a camera rotation to occur at all, due to very small mouse movements, such as a small amount of mouse jitter.

When testing this issue in my project, I found that the problem was not with the function that updated the rotation of the camera, but rather with the Mouse.SetPosition function. When I commented out the slice of code where the mouse position was being reset to the middle of the screen, the stuttering stopped.

But what you wrote is definitely something to look out for. Did you come across any threads/articles on preventing mouse jitter affecting the input? I am curious as to what amount of x and y movement could be used as threshold so that jittering is prevented, but the camera movement does not seem delayed or dampened.

You are right. For me it is fixed perfectly. For someone else as well. But two others are having some issues with it. It does stutter for them at random moments.

I have already tried to do it with a timer. As in after this many seconds reset, but that makes it spin like crazy.
The other method I have tried is, checking if the deltaX and deltaY are bigger or smaller than certain values. But up to this point this isn’t working either. But sometimes it does work and then It either stutters a bit, or it moves the screen like a maniac.

Sorry for reopening this post. But do you then have any idea how we might be able to make it work?

Thanks to everyone who responds:)