Making the player face the mouse, how should I go about it?

Alright so basically what my script does is make your character face the direction the mouse is facing while the q key on your keyboard is being held down. I’ve made this post because I’m trying to find a better way to go about this.Here’s my code.


inputService.InputBegan:Connect(function(Key, GameStuff)
	if GameStuff and not CanClick then return end
		if Key.KeyCode == Enum.KeyCode.Q then
			CanClick = false
			Holding.Value = true
		end
end)


inputService.InputEnded:Connect(function(Key, GameStuff)
	if GameStuff then return end
	if Key.KeyCode == Enum.KeyCode.Q then
		CanClick = true
		Holding.Value = false
	end
end)



mouse.Move:Connect(function()
	if Holding.Value ~= true then return end
	Root.CFrame = CFrame.new(Root.Position, Root.Position + Vector3.new(mouse.Hit.lookVector.x, mouse.Hit.lookVector.y, mouse.Hit.lookVector.z))
	wait(.1)
end)


How would you guys go about this and what methods would you guys use to create a better version of this? All replies are appreciated as I’m an intermediate programmer trying to improve and i believe feedback on improving my code is one step closer to achieving that goal.

9 Likes

This should be in #development-support:requests-for-code-feedback

edit: he has now moved it to the correct channel but thanks for the flag

4 Likes

For what you’re doing, you’re better off using IsKeyDown. You’re also probably okay with not adding a wait to the Move event. It’s also redundant to recreate the lookVector.

Here’s my code (in StarterCharacterScripts) that does the same thing but is much less bloated:

local UserInputService = game:GetService("UserInputService")
local Mouse = game:GetService("Players").LocalPlayer:GetMouse()
local Root = script.Parent:WaitForChild("HumanoidRootPart")

Mouse.Move:Connect(function()
	if not UserInputService:IsKeyDown(Enum.KeyCode.Q) then return end
	Root.CFrame = CFrame.new(Root.Position, Root.Position + Mouse.Hit.LookVector)
end)
11 Likes

The problem with setting the CFrame of the player’s root part is that for other players it will look choppy. Instead, if the player isn’t anchored, you should create a BodyGyro and change the CFrame of that instead. You can do this in a local script as well, since the player’s body CFrame replicates all the time.

Also, if you only want the player to rotate only side to side, not up and down, use this line of code instead (pp being the character’s primary part (root)):

gyro.CFrame = CFrame.new(pp.Position, Vector3.new(mouse.Hit.p.X, pp.Position.Y, mouse.Hit.p.Z)) 

This is especially useful if you’re going for a top-down view game.

Lastly, I would check if the player is alive, and only if they are update the CFrame, otherwise you’ll have a spinning root part on the floor.

23 Likes

Hi, so I’ve tried using bodyGyro to make the character face the cursor but as mentioned before, it doesn’t work perfectly if your moving or/and if your camera is angled. I suggest using something like this instead.

game:GetService("RunService").RenderStepped:Connect(function()
    local forwardVector = (character.HumanoidRootPart.Position - mouse.hit.Position).Unit
    local rightVector = forwardVector:Cross(Vector3.new(0,1,0))
    local cframe = CFrame.fromMatrix(character.HumanoidRootPart.Position, -rightVector, Vector3.new(0, 1, 0))
	
    character.HumanoidRootPart.CFrame = cframe
end)

The code could probably be improved, but this is what I use and it works perfectly. It’s also more reliable then the servers physics.

Note this code only adjusts the side orientation of the humanoidRootPart, it won’t make your character look up/down.

You are using mouse.hit which is not that good because it only is for when mouse is clicked on a certain position