My goal is to have the character look at the mouse smoothly and consistently
the issue is that if a player hovers over different objects the rotation can get choppy
local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local character = script.Parent
local primary = character.PrimaryPart
local mouse = player:GetMouse()
mouse.TargetFilter = character
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.Parent = primary
bodyGyro.D = 40
bodyGyro.P = 10000
bodyGyro.MaxTorque = Vector3.new(4000000, 4000000, 4000000)
while true do
local mousePos = mouse.Hit.Position
local primaryPos = primary.Position
local lookatPos = Vector3.new(mousePos.X, primaryPos.Y, mousePos.Z)
bodyGyro.CFrame = CFrame.new(primaryPos, lookatPos)
RunService.Heartbeat:Wait()
end
I know a solution to this is to make a new ray and have an ignore list, but I’d rather not have to add things to a list every time I update the map, or update a whitelist if I go that route
is there a way to do this without mouse.Hit, or a way to make mouse.Hit work properly without a ignore/whitelist?
Here is your solution:
Calculate a 3D ray from 2D camera origin and mouse position. With your mouse ray, calculate the ray-plane intersection from the plane formed by the characters y-position. Just give a normal going straight up if the character is assumed to always be standing upright. Use the plane intersection position as the ‘looking’ direction.
local Camera = workspace.CurrentCamera
local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()
local RunService = game:GetService("RunService")
wait(0.5)
local player = game.Players.LocalPlayer
local character = player.Character
local primary = character.PrimaryPart
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.Parent = primary
bodyGyro.D = 40
bodyGyro.P = 10000
bodyGyro.MaxTorque = Vector3.new(4000000, 4000000, 4000000)
local function rayPlane(planepoint, planenormal, origin, direction)
return -((origin-planepoint):Dot(planenormal))/(direction:Dot(planenormal))
end
while true do
local ray = Camera:ScreenPointToRay(Mouse.X, Mouse.Y)
local t = rayPlane(Player.Character.Head.Position, Vector3.new(0, 1, 0), ray.Origin, ray.Direction)
local primaryPos = primary.Position
local plane_intersection_point = (ray.Direction * t) + ray.Origin
bodyGyro.CFrame = CFrame.new(primaryPos, plane_intersection_point)
RunService.Heartbeat:Wait()
end
Sorry to bump this post but after trying your code out I noticed that if I aim in the sky or somewhere very far away my character looks in the opposite direction. Any idea why?
local Camera = workspace.CurrentCamera
local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()
local RunService = game:GetService("RunService")
wait(0.5)
local player = game.Players.LocalPlayer
local character = player.Character
local primary = character.PrimaryPart
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.Parent = primary
bodyGyro.D = 40
bodyGyro.P = 10000
bodyGyro.MaxTorque = Vector3.new(4000000, 4000000, 4000000)
local function rayPlane(planepoint, planenormal, origin, direction)
return -((origin-planepoint):Dot(planenormal))/(direction:Dot(planenormal))
end
while true do
local ray = Camera:ScreenPointToRay(Mouse.X, Mouse.Y)
local t = rayPlane(Player.Character.Head.Position, Vector3.new(0, 1, 0), ray.Origin, ray.Direction)
local primaryPos = primary.Position
local plane_intersection_point = (ray.Direction * t) + ray.Origin
bodyGyro.CFrame = CFrame.new(primaryPos, Vector3.new(plane_intersection_point.X, primaryPos.Y, plane_intersection_point.Z))
RunService.Heartbeat:Wait()
end
I think this was it, but it’s been a long time so I don’t remember clearly
and @Paintertable sorry for the late response, I do not sorry @jody7777 wrote that bit of code, so if you still need help they would be one the to ask