Mouse issues, need help

Hello, I made a script that makes the player turn towards the direction the mouse is pointing horizontally (X).

My problem is that when I bring the mouse closer to the player, the camera goes crazy, making the player spin non-stop and bugging it.

-- LocalScript / StarterCharacterScripts

-- Rotate Character (it replicates in client and server)

task.spawn(function()
	while task.wait() do
		local body = char:WaitForChild("HumanoidRootPart")
		local look = CFrame.new(body.Position,mouse.Hit.Position)
		local x,y,z = look:ToOrientation()
		
		body.CFrame = CFrame.new(look.Position) * CFrame.Angles(0,y,z)
	end
end)

Any solution you can give me please?

3 Likes

im bad at explaining stuff but i just added 1 stud to the position the char will look at so it wont try to look directly below it

task.spawn(function()
	while task.wait() do
		local body = char:WaitForChild("HumanoidRootPart")
		local front = (body.CFrame + body.CFrame.LookVector * Vector3.new(1, 0, 1))
		local look = CFrame.new(body.Position,mouse.Hit.Position+front.Position)
		local x,y,z = look:ToOrientation()

		body.CFrame = CFrame.new(look.Position) * CFrame.Angles(0,y,z)
	end
end)
1 Like

It solves the problem, but now there is another even worse problem, when moving the camera, it works in a strange way, it does not rotate correctly

First, remove the Y component of your positions, e.g.:

local bodyPos = body.Position * Vector3.new(1,0,1)

ore equivalently:

local bodyPos = Vector3.new(body.Position.X, 0, body.Position.Z)

Do the same with mouse.Hit.Position. This will ensure that CFrame.new(p1,p2) gets you a CFrame that is “upright”, with just Yaw rotation, not trying to tilt your character.

Then, ignore the mouse hit position if it’s too close to the character. e.g. if (mouseHitPos - bodyPos).Magnitude < 1 or something like that. If the mouse hit position is too close to your character, the direction will become numerically unstable (the “when you’re at the South Pole, every direction is North” singularity problem)

Last, ignore the mouse hit position if the hit part is actually part of your character, otherwise the character’s going to move while the mouse is still hovering over it, and you’ll get rapid jitter from the hit position changing when the character moves. Alternately, you can ditch mouse.Hit altogether and manually raycast using a ray from Camera:ViewportPointToRay() and exclude the character from the raycast params.

Also, this:
body.CFrame = CFrame.new(look.Position) * CFrame.Angles(0,y,z)

should now be:
body.CFrame = look + body.CFrame.Position

If you just use XZ-plane vectors, you don’t need to go to Euler angles and back (which has its own problems)

I tried to formulate your answer but now the player cannot function correctly when turning, I don’t know if I have misunderstood, could you please rewrite the code?

Sorry, I am very confussed :sweat_smile:

This is what I understood when writing the code

local body = char:WaitForChild("HumanoidRootPart")
local look = CFrame.new(body.Position,mouse.Hit.Position)
		
local bodyPos = body.Position * Vector3.new(1,0,1)
local mouseHitPos = body.Position * Vector3.new(1,0,1)
if (mouseHitPos - bodyPos).Magnitude < 1 then
	body.CFrame = look + body.CFrame.Position
end

It takes me flying and the game crashes

You have body.Position twice, where the second should be mouse.Hit.Position

After that, you need:
local look = CFrame.new(bodyPos,mouseHitPos)

Your code still creates “look” from the original positions with the Y component still intact.

So, overall:

local body = char:WaitForChild("HumanoidRootPart")
		
local bodyPos = body.Position * Vector3.new(1,0,1)
local mouseHitPos = mouse.Hit.Position * Vector3.new(1,0,1)
local look = CFrame.new(bodyPos ,mouseHitPos )
if (mouseHitPos - bodyPos).Magnitude > 1 then
	body.CFrame = look + body.CFrame.Position
end

EDIT: When I added the revised code, I saw that you had the Magnitude check backwards, the code should run for magnitude > 1, not < 1.

Also, these changes also don’t address the issue of the mouse hit part being part of the character that’s rotating, which is still something you have to explicitly check for. The radius of 1 check is only meant to avoid the singularly, not exclude the character. If you make the radius bigger than the character, it would solve that problem, but you’ve have a noticable dead zone around the character which will feel bad.

It is not what I expected but at the same time you helped me to place the magnitude correctly, I was confused but I already clarified my doubts

task.spawn(function()
	while task.wait(0.01) do
		local body = char:WaitForChild("HumanoidRootPart")
		
		
		local look = CFrame.new(body.Position,mouse.Hit.Position)
		local mouseHitPos = mouse.Hit.Position * Vector3.new(1,0,1)
		local bodyPos = body.Position * Vector3.new(1,0,1)
		
		local x,y,z = look:ToOrientation()
		
		if (mouseHitPos - bodyPos).Magnitude > 1 then
			body.CFrame = CFrame.new(look.Position) * CFrame.Angles(0,y,z)
		end
	end
end)

I combined one of the things you gave me instructions on and my code, and it worked correctly. Thank you so much

1 Like

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