How can I recreate Roblox movement?

So I am trying to create a game where you have to control two players and they have the same movement keybind and they move the exact same, the problem I am having is that I am trying to recreate roblox movement based on camera, I have found a solution but it is quite buggy.

I have a dictionary holding all the keycodes related to which direction it should make you move.

local keyToDirectionMap = {
	
	[Enum.KeyCode.W] = Vector3.new(0,0,-1),
	[Enum.KeyCode.A] = Vector3.new(-1,0,0),
	[Enum.KeyCode.S] = Vector3.new(0,0,1),
	[Enum.KeyCode.D] = Vector3.new(1,0,0),
	
}

Then I make sure that the input is a WASD key and make the variable direction a new Vector3. I then set direction equal to

direction + cam.CFrame:VectorToWorldSpace(keyToDirectionMap[keyCode])

Here is the full function.

local function keyToDirection()
	
	local direction = Vector3.new()
	
	
	
	for keyCode, isPressed in pairs(isKeyPressed) do
		if isPressed and keyCode ~= Enum.KeyCode.Space then
			
			direction =  direction + cam.CFrame:VectorToWorldSpace(keyToDirectionMap[keyCode])
			
		end
	end
	
	return direction
	
end

When it returns it will return as a Vector3 that will make the character seem like it moves normally, but problems start when you are suspended in the air.

Youtube Video

As you can see it works alright until I jump, if you look in the properties I have shown, you will see the Y value of the Humanoid.MoveDirection is being changed whenever I move the camera up and down. Then when I go to do the obby jumps, if I keep the camera straight it works fine but when the camera is tilted up the Y value is being changed so that it messes with the speed of the jump and you are slowed down while jumping. I have searched online on how I should go about creating camera based movement, I have tried setting the Y value to 0. But none of that has worked. I know that the problem is the

cam.CFrame:VectorToWorldSpace(keyToDirectionMap[keyCode])

Could someone find a way to calculate the Vector3 that would work in this situation?

The angle of the camera’s CFrame on the x-axis is the main issue since, whenever that moves, it contributes to the rotation of the CFrame:VectorToWorldSpace(). So, you’d have to create a new CFrame without the camera’s vertical rotation. IIRC, that angle of the camera initially is set to 0. Therefore, that’s the angle you should set the camera to.

I believe it’s as simple as doing this:

local camCFrame = cam.CFrame
local _, camY, camZ = camCFrame:ToOrientation()
local camNoYCFrame = CFrame.new(camCFrame.Position) * CFrame.Angles(0, camY, camZ)

-- and then use that for the direction instead
direction += camNoYCFrame:VectorToWorldSpace(keyToDirectionMap[keyCode])

Hopefully this helps! (If it doesn’t you can also yell at me for that)

1 Like

Sorry but this doesn’t work, I have tried altering it but I can’t find a solution. I don’t know why removing the Y value makes it so that you move based on the world origin and not based off your camera.

Wait, nevermind it works perfectly, I just put it into the function like this

local function keyToDirection()
	
	local direction = Vector3.new()
	
	
	
	for keyCode, isPressed in pairs(isKeyPressed) do
		if isPressed and keyCode ~= Enum.KeyCode.Space then
			
			local camCFrame = cam.CFrame
			local _, camY, camZ = camCFrame:ToOrientation()
			local camNoYCFrame = CFrame.new(camCFrame.Position) * CFrame.Angles(0, camY, camZ)
			
			direction =  direction + camNoYCFrame:VectorToWorldSpace(keyToDirectionMap[keyCode])
			
		end
	end
	
	return direction
	
end

and it works exactly like default Roblox movement. I had already done that before posting the it doesn’t work reply so I must have had changed a value or something. Thanks for your help!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.