How to move player relative to camera direction?

I am trying to make a flight ability for my game, and I got it working except for the movement. I want the character to move in the camera’s direction when they walk forwards, and move to the camera’s right when they walk right, etc. So basically, normal movement, but when they look up, they move up instead of forwards. I’ve tried all sorts of stuff with the camera cframe and object to world space and world to object space, but none of it works properly.
The closest I’ve gotten so far is:

local cf = workspace.CurrentCamera.CFrame
local dir = cf:VectorToObjectSpace(player.Character.Humanoid.MoveDirection * 10)
local direction: Vector3 = (cf.LookVector * -dir.Z) - Vector3.new(0, dir.Y, 0) + (cf.RightVector * dir.X)

The thing with this is the Y movement is a little too fast. I don’t know what to do.

The Move() function of a humanoid has, after the move direction Vector3, a parameter called “relative to camera”, so use that

I’m not actually moving the humanoid, so I need a direction to move in for my AlignPosition object - I add the direction to the current position.

So you want to use AlignPosition (constraints) to move the character, aswell as setting the LookVector Y of the character to 0…?

sorry for my stupid keyboard

Yes, I am using constraints to move the character, but the character doesn’t have a look vector…
I am using the player’s move direction (which is a unit vector indicating the direction the player is trying to move) and trying to rotate it such as that it also goes up when the player looks up. The move direction is on a flat plane by default, so the Y is always zero.

For example, when the camera is looking straight ahead (say, -Z) then when the player pressed W, then the character will move towards -Z. When the camera is looking at +X, then the character will move towards +X when they press W. This is what the normal behavior is, but it doesn’t work because I also want it so when the camera is looking at +Y, the character will move towards +Y.

Not really familiar with vector.Unit, but something that might help you is how the core movement code for Keyboard calculates the MoveVector. I’m on phone so I can’t give you the code piece directly, but it goes about binding 4 functions using ContextActionService, then checking for the InputState and all of that, while setting a DirectionsTable.Forward to either 0 or -1, depending on the InputState. Same for Left, Right, Backward and in between. This should help creating the MoveVector. Different business making that vector relative to the camera

I got it working! Here’s the working code:

local cf = workspace.CurrentCamera.CFrame.Rotation
local dir: Vector3 = cf:VectorToObjectSpace(player.Character.Humanoid.MoveDirection * 10)
local direction: Vector3 = Vector3.new(0,0,0)
if dir.Magnitude ~= 0 then
	direction = cf:VectorToWorldSpace(Vector3.new(dir.X, 0, dir.Z).Unit * dir.Magnitude)
end

I had to do the magnitude check because if the magnitude was zero, then the unit vector was filled with NaN and caused errors.