#Camera3D help

1 messages · Page 1 of 1 (latest)

dense helm
#

Hi, I'm trying to figure out how to make a player face the direction a camera is looking when pressing "move_forward". The camera attached to a SpringArm3D which is a child of Player.

This is my code so far

private void RotatePlayerToCamera()
{
    // 1) Freeze this camera so it ignores the player's transform:
    TopLevel = true;

    // 2) Read this camera’s world‐space yaw & pitch:
    Vector3 camGlobalEuler = SpringArm.GlobalTransform.Basis.GetEuler();
    float globalCamPitch = camGlobalEuler.X;
    float globalCamYaw   = camGlobalEuler.Y;
    GD.Print($"camPitch = {globalCamPitch}");
    GD.Print($"camYaw = {globalCamYaw}");
    Vector3 camRelativeEuler = SpringArm.Transform.Basis.GetEuler();
    float relativeCamPitch = camRelativeEuler.X;

    // 3) Snap the player’s Y‐rotation to match the camera’s world‐space yaw:
    Vector3 playerRot = Player.Rotation;
    playerRot.Y = globalCamYaw;
    GD.Print(Player.Rotation);
    Player.Rotation = playerRot;
    GD.Print(Player.Rotation);

    // 4) Force this camera’s local rotation: keep pitch, zero out yaw
    Rotation = new Vector3(globalCamPitch, 0f, 0f);

    // 7) Unfreeze the camera so it again follows the player:
    TopLevel = false;
    Position = StationaryPosition.Position;
}

The problem is that it spins like crazy and inverts the camera at some point so moving my mouse right will move it one way, then move the other way somehow

azure imp
#

it seems like you have the right idea, there's just a few details that are off:

  • you'll want to use the global rotation of the camera, not necessarily the spring arm
  • I'm not sure you need the TopLevel stuff at all
  • you shouldn't need to rotate the camera again, this is probably whats causing the spinning
#

I don't know Godot C# very well but here's basically what you would do in GDScript and you can probably figure out how to convert it:

Player.GlobalRotation.y = camera.GlobalRotation.y
#

that's about it

#

if that doesn't work you might need to do some vector projection

#

actually this might work better in some cases:

Vector3 dir = camera.GlobalRotation.slide(Vector3.UP);
Player.GlobalRotation.y = dir.y
dense helm
#

I'll give that a try

azure imp
#

this code seems like AI btw, is it?

dense helm
#

the problem is that I want to be able to rotate teh camera without it rotating the player, but only have it only do the direction change when pressing move_forward

#

and yeah basically

#

there is no documentation for C#

azure imp
#

well sorta

dense helm
#

only for tutorials

azure imp
#

most (if not all) of the methods do the same things, they are just capitalized differently

#

there's just a couple things you can do in the editor that you can't do in C#

#

but the syntax is different for sure

dense helm
#

when we rotate the player, since the springarm is a child of the player it also rotates

azure imp
#

oh then try the top level stuff

#

later on you should probably just make the spring arm permanently top level

dense helm
#

then it wont follow the player

azure imp
#

you would have to make it follow the player

#

with code

#

if you turn on top level then turn it back off, won't the camera just snap to where it's supposed to be relative to the player?

#

genuinely asking idk

dense helm
#

I just tried when i turn it off, and turn it back on, it just attaches from where it is now

azure imp
#

oh nice

#

then yeah the TopLevel toggle you were doing in the beginning works

dense helm
#

I realized why i was runnig my head through the wall

#

gpt took the pitch of the springarm, and then applied it to the root pivot node instead of applying it back onto the springarm

azure imp
#

that'll do it!

dense helm
#

that being said it also did fancy atan math stuff i would never in my life understand

#

it works now

azure imp
#

nice!

dense helm
#

though leftrightback still need to be implemented

azure imp
#

it's gonna be the same idea

#

back is going to be -y

#

left and right will be toughter since it's on the XZ plane, not just asking for one direction

#

well ackshually

#

that dir vector we made before?

#

you can use that

#
forward = dir
backward = -dir
left = dir.rotated(Vector3.UP, deg_to_rad(90))
right = dir.rotated(Vector3.UP, deg_to_rad(-90))
#

and you can just use the y of each same as for forward

dense helm
#

math

azure imp
dense helm
azure imp
#

nah bro it's not so bad

#

yellow is the direction the camera is looking

#

blue is the y direction of the camera

#

so blue is dir/forward

#

green is left

#

red is backward

#

purple is right

dense helm
#

makes sense so far other than the fact that I am confused on the camera lol

azure imp
#

it's just a bad drawing lol

#

try to picture that yellow is the direction the camera is facing

#

then the blue dotted line is like taking that angle and snapping it to the XZ plane

#

so x and z are both 0, we are left with just y

#

then we can just rotate the blue one around

#

to get which direction we should face

dense helm
#

hm ok

#

i will try my best

azure imp
dense helm
#

ok right now the camera stuff works but movement is decoupled from camera so ineed to fix that

azure imp
#

do you want help with that or do you think you can figure it out

dense helm
#

I'll give it a shot first

#

thank you so much for help with the camera tho i am extremely weak in the maths

#

even though i shouldnt be

azure imp
#

no problem! happy to help

dense helm
#

I'm trying to make it smooth now, do you have any idea how to smoothly transition between front left right and back? like if i hold both w and d i want to diagonally go forward-right

#

@azure imp I broke it when i tried to add another thing

azure imp
#
  1. you could probably use a Tween to do it. Basically it smoothly changes a property over a specified time
  2. are you using Git
zealous pawn
#

I'm not 100% following along, but to get the yellow to blue, you can use -camera.basis.z to get the direction the camera is facing, then multiply that by 1 minus the up direction (if your character is not going to be wall running, you can simplify this to just a Vector(1.0, 0.0, 1.0) ) to flatten the camera's direction. Then you can normalize it and this is now your forward direction

#

could also save the mouse / input to rotation in a separate script and pass it as needed. For instance, you get the player's mouse movement and increment / decrement pitch and yaw floats accordingly, every frame you pass that value to the camera so the camera is always properly rotating, however, you only pass that data to character on wasd input. When you get a wasd input, you set the camera's yaw rotation = 0 and change the character's yaw instead of the camera's.

azure imp
#

I made the solution this way because I generally distrust euler angles, so I wanted to distill the vector down to just a y rotation

zealous pawn
#

I see, I see

#

A lot of my experience with movement is from making this blob game where you can stick to multiple surfaces, so I had to work off both the camera direction and the normal of the surface the player is walking on

#

Also, might be helpful to ask chatgpt about quaternions