#FPS Camera Rotating the wrong way

48 messages · Page 1 of 1 (latest)

rotund ember
#

Hey so I'm new to Godot and im trying to make a FPS Camera movement script but kinda having a issue, I think i need to clamp the camera movement but I'm not sure how

#
    public override void _UnhandledInput(InputEvent @event)
    {
        if(Input.IsKeyPressed(Key.Escape))
        {
            Input.MouseMode = Input.MouseModeEnum.Visible;
            

        }
        if(@event is InputEventMouseMotion)
        {
            InputEventMouseMotion a = (InputEventMouseMotion) @event;
            //this.RotateY(a.Relative.X * camSensitivity * -1 * Convert.ToSingle(GetProcessDeltaTime()));
            GD.Print(this.Rotation.X);
            this.RotateX(a.Relative.Y * camSensitivity * -1 * Convert.ToSingle(GetProcessDeltaTime()));
        }
    }
crisp flint
#

what is the issue here?

rotund ember
#

One second let me quickly get a video of whats happening

#

if the this.rotatey function was uncommented this would happen

#

im not sure why its rotating like that, i just want it to rotate like a standard FPS camera would but 🤷‍♀️

crisp flint
#

looks a bit like a gimbal lock thing to me.
try changing the order of rotations or maybe use a pivot node parent to keep the rotations separate

rotund ember
#

do you mind showing a example on how to do that?

crisp flint
#

okay, lets start with node hierarchy, can you put up a screenshot how it looks like for the player scene?

rotund ember
crisp flint
#

first, lets make the camera a child of the player, so you make sure it moves where the player moves too

#

(I guess the characterbody is your player)

rotund ember
#

At the moment im just trying to make the camera movement seperate from the player controller

#

unless thats where im going wrong, i do have a character in the level but its literally just using the example code that godot has when you generate a script that inherits characterbody3d

crisp flint
#

ah, okay. then just create a new node named 'pivot' and put the camera under this new node

rotund ember
#

Like this?

crisp flint
#

yes. I think you need a Node3D, you can change it via rightclick -> change type

rotund ember
#

There now its a Node3D

crisp flint
#

now, coming back to the camera script, you can change

            this.RotateX(a.Relative.Y * camSensitivity * -1 * Convert.ToSingle(GetProcessDeltaTime())); 

to

            GetParent().RotateX(a.Relative.Y * camSensitivity * -1 * Convert.ToSingle(GetProcessDeltaTime())); 
#

this might already work like this

rotund ember
#

Should i change it to GetParent().Rotation.RotateX?

crisp flint
#

ah, sorry, then do GetParent<Node3D>().RotateX

#

wait

#

now^^

rotund ember
#

ok so now its doing something incredibly weird, let me quickly get a video of it

crisp flint
#

the cameras transform might not be 0

#

can you open the camera node in the inspector and click this?

rotund ember
#

The camera transform is now 0 but its still kinda doing the first issue again

crisp flint
rotund ember
#

How do i clamp the pivot?

crisp flint
#

something like this:

 Node3D pivot = GetParent<Node3D>();
 float xClamped = Mathf.Clamp(pivot.Rotation.X, -1.2f, 1.2f);
 pivot.Rotation = new Vector3(xClamped, pivot.Rotation.Y, pivot.Rotation.Z);        

not sure if theres a simpler way

rotund ember
#

yea still doing it :/

crisp flint
#

do you have any rotations on the pivot or camera nodes?

rotund ember
#

Nope

crisp flint
#

oh, maybe you need to do the y-rotation on the pivot and x-rotation on the camera

rotund ember
#

wait give me a couple minutes

safe shell
#

i could send a script that i used from a tutorial

#

nvm it was for godot 3

#

MY BAD

honest thicket
#

You could do something like this inside your character controller:

private Vector3 viewAngles = Vector3.Zero;
private Vector2 mouseDelta = Vector2.Zero;

...
// IMPORTANT: do this in _Process, NOT THE INPUT HANDLING METHODS
viewAngles.Y -= mouseDelta.X;
viewAngles.X -= mouseDelta.Y;

// clamp viewAngles here and whatnot

...

camera.Rotation = viewAngles;
mouseDelta = Vector2.Zero;```You would use `e.Relative` to determine `mouseDelta`, and of course obtain a reference to your camera node before all that
#

Here's how I do my mouseDelta:

if ( @event is InputEventMouseMotion && Input.MouseMode == Input.MouseModeEnum.Captured )
{
    var mouseMotion = @event as InputEventMouseMotion;
    mMousePositionDelta += mouseMotion.Relative;
}```
The `Input.MouseMode` check is just to see if the player's using a menu, as to avoid rotating there
#

So TL;DR viewAngles should be a member of your character controller, and over time it just changes with mouse motion

#

And it gets applied to the camera

#

Oh yeah mouseDelta is also a member

#

There we go, updated pseudocode