Player Rotation to mouse position not working

What I want to achieve:
I want the player to move towards the mouse. When holding W, the player moves in the direction of the mouse, when holding A the player moves to the left of the mouse.

What I have right now:
https://gyazo.com/748c17fc7b4d48c6ef91f8bd63a0651c

The player rotates towards the mouse. When the player is looking at the mouse, I want this to be the movement


And that for every possible locaton of the mouse.

I’m having difficulties trying to explain this, but I hope you guys understand.

My question:
Are there already forum posts about this? (I couldn’t find one)
How would I acieve something like this?

1 Like

Well, there are two options. None of them are optimal

  • Changing the camera to face the mouse
  • Making your own walking script

Yeah, @ThanksRoBama has made a replica of the default player movement script in this post which is relative to the camera.

Basic movement scripts
local RunS = game:GetService("RunService")
local InputS = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()

player.CharacterAdded:Connect(function(_character)
	character = _character
end)

local walkKeyBinds = {
	Forward = { Key = Enum.KeyCode.W, Direction = Enum.NormalId.Front },
	Backward = { Key = Enum.KeyCode.S, Direction = Enum.NormalId.Back },
	Left = { Key = Enum.KeyCode.A, Direction = Enum.NormalId.Left },
	Right = { Key = Enum.KeyCode.D, Direction = Enum.NormalId.Right }
}

local function getWalkDirectionCameraSpace()
	local walkDir = Vector3.new()

	for keyBindName, keyBind in pairs(walkKeyBinds) do
		if InputS:IsKeyDown(keyBind.Key) then
			walkDir += Vector3.FromNormalId( keyBind.Direction )
		end
	end

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector
	end
	
	return walkDir
end

local function getWalkDirectionWorldSpace()
	local walkDir = camera.CFrame:VectorToWorldSpace( getWalkDirectionCameraSpace() )
	walkDir *= Vector3.new(1, 0, 1) --Set Y axis to 0

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector
	end

	return walkDir
end

local function updateMovement( dt )
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid:Move( getWalkDirectionWorldSpace() )
	end
end	

RunS.RenderStepped:Connect(updateMovement)

The solution should be to make it relative to how the character is facing which is controlled by the mouse instead of the camera by editing the getWalkDirectionWorldSpace() function above to make it relative to the CFrame of the players HumanoidRootPart.CFrame instead of the cameras CFrame

So yeah here, I replaced the camera.CFrame with the humanoidRootPart.CFrame insert it into starter local player scripts.

Modified default movement script:
local RunS = game:GetService("RunService")
local InputS = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
player.CharacterAdded:Connect(function(_character)
	character = _character
	humanoidRootPart = _character:WaitForChild("HumanoidRootPart")
end)

local walkKeyBinds = {
	Forward = { Key = Enum.KeyCode.W, Direction = Enum.NormalId.Front },
	Backward = { Key = Enum.KeyCode.S, Direction = Enum.NormalId.Back },
	Left = { Key = Enum.KeyCode.A, Direction = Enum.NormalId.Left },
	Right = { Key = Enum.KeyCode.D, Direction = Enum.NormalId.Right }
}

local function getWalkDirectionCameraSpace()
	local walkDir = Vector3.new()

	for keyBindName, keyBind in pairs(walkKeyBinds) do
		if InputS:IsKeyDown(keyBind.Key) then
			walkDir += Vector3.FromNormalId( keyBind.Direction )
		end
	end

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector
	end

	return walkDir
end

local function getWalkDirectionWorldSpace()
	local walkDir = humanoidRootPart.CFrame:VectorToWorldSpace( getWalkDirectionCameraSpace() )
	walkDir *= Vector3.new(1, 0, 1) --Set Y axis to 0

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector
	end

	return walkDir
end

local function updateMovement( dt )
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid:Move( getWalkDirectionWorldSpace() )
	end
end	

RunS.RenderStepped:Connect(updateMovement)

Make sure to use your own humanoid rotation method and disable autorotate or else it’ll be funky, but I believe you have already done that.

4 Likes

Eyyyyy, thanks man! This is great :slight_smile:

1 Like