I am trying to make a tool which on the client is being pointed to wherever the player is pointing. I already managed to get the vertical axis done with the help of this post, but i cant figure out how to make it work for the horizontal axis as well.
I am terrible with CFrames, so I don’t really know what to do here.
This is my current code:
local Camera = workspace.CurrentCamera
local Player = game.Players.LocalPlayer
local char = Player.Character
local origRightS = char:WaitForChild("RightUpperArm"):WaitForChild('RightShoulder').C0
local origNeck = char:WaitForChild("Head"):WaitForChild("Neck").C0
local m = Player:GetMouse()
local IsEquipped = false
script.Parent.Equipped:Connect(function()
origRightS = char:WaitForChild("RightUpperArm"):WaitForChild('RightShoulder').C0
origNeck = char:WaitForChild("Head"):WaitForChild("Neck").C0
renderconnec = game:GetService("RunService").RenderStepped:Connect(function()
if char:FindFirstChild("RightUpperArm") then
char.RightUpperArm.RightShoulder.C0 = char.RightUpperArm.RightShoulder.C0:Lerp(CFrame.new(char.RightUpperArm.RightShoulder.C0.Position) * CFrame.Angles(-math.asin((m.Origin.p - m.Hit.p).unit.y), 0, 0) , 0.1)
end
if char.Head:FindFirstChild("Neck") then
char.Head.Neck.C0 = char.Head.Neck.C0:Lerp(CFrame.new(char.Head.Neck.C0.Position) * CFrame.Angles(-math.asin((m.Origin.p - m.Hit.p).unit.y), 0, 0), 0.2)
end
end)
end)
script.Parent.Unequipped:Connect(function()
if renderconnec then
renderconnec:Disconnect()
end
if char:FindFirstChild("RightUpperArm") then
char.RightUpperArm.RightShoulder.C0 = origRightS
end
if char:FindFirstChild("LeftUpperArm") then
char.LeftUpperArm.LeftShoulder.C0 = origLeftS
end
if char.Head:FindFirstChild("Neck") then
char.Head.Neck.C0 = origNeck
end
end)
Edit: sorry for the music, didnt know i was also recording audio
Here. I also changed the speed of the lerp so that it’s consistent with any framerate. You can play around with the number a little. Basically what I did was just use your code for the y axis, and do the same thing for the x axis, but instead of getting the mouse.hit.y i did mouse.hit.x and then I removed the - at the start. idek tbh but it works lol. oh yeah i did it for the head too. if you dont want that js remove the “x” in the head part of the code and replace it with a 0
local Camera = workspace.CurrentCamera
local Player = game.Players.LocalPlayer
local char = Player.Character
local origRightS = char:WaitForChild("RightUpperArm"):WaitForChild('RightShoulder').C0
local origNeck = char:WaitForChild("Head"):WaitForChild("Neck").C0
local m = Player:GetMouse()
local IsEquipped = false
local moveSpeed = 1 -- 1 is default, increase or decrease by a few decimals
script.Parent.Equipped:Connect(function()
origRightS = char:WaitForChild("RightUpperArm"):WaitForChild('RightShoulder').C0
origNeck = char:WaitForChild("Head"):WaitForChild("Neck").C0
renderconnec = game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
local lerpSpeed = (60*1) / (1/deltaTime)
local mHit = char.PrimaryPart.CFrame:ToObjectSpace(m.Hit)
local x = math.asin((m.Origin.p - mHit.p).unit.x)
if char:FindFirstChild("RightUpperArm") then
char.RightUpperArm.RightShoulder.C0 = char.RightUpperArm.RightShoulder.C0:Lerp(CFrame.new(char.RightUpperArm.RightShoulder.C0.Position) * CFrame.Angles(-math.asin((m.Origin.p - mHit.p).unit.y), x, 0) , lerpSpeed)
end
if char.Head:FindFirstChild("Neck") then
char.Head.Neck.C0 = char.Head.Neck.C0:Lerp(CFrame.new(char.Head.Neck.C0.Position) * CFrame.Angles(-math.asin((m.Origin.p - mHit.p).unit.y), x, 0), lerpSpeed)
end
end)
end)
script.Parent.Unequipped:Connect(function()
if renderconnec then
renderconnec:Disconnect()
end
if char:FindFirstChild("RightUpperArm") then
char.RightUpperArm.RightShoulder.C0 = origRightS
end
if char:FindFirstChild("LeftUpperArm") then
char.LeftUpperArm.LeftShoulder.C0 = origLeftS
end
if char.Head:FindFirstChild("Neck") then
char.Head.Neck.C0 = origNeck
end
end)
Thanks so much! I was fiddling around with the values and changing x with y and stuff but for some reason only could get it to work when the player was facing a certain direction.
Edit: it did work finnicky for objects close by, so i changed mHit to the following:
local mHit = char.PrimaryPart.CFrame:ToObjectSpace(m.Hit) * CFrame.new(0,0,-1000)
I tried some more testing, but unfortunately got this weird issue when pointing at parts and being far away from 0,0,0. When I point into the distance it works fine, but when something is closer it does this. Do you know why?
Realism does this (but I think it only points exactly at the mouse when the character is facing towards the mouse):
You could make it do what you want if you have a script that faces the character towards the mouse (or at least within a 45 degree angle). You could do that with body movers (e.g. align orientation).
I was thinking it might work in shift lock too (or something similar that forces the player to face roughly in the direction of the mouse), but that might not be the look you’re going for.
After hours of stress and trying stuff out, I managed to get something working with the help of this post. This is my current code and it does not have any weird issues like mentioned before!
local Player = game.Players.LocalPlayer
local origRightS = nil
local origNeck = nil
local mouse = Player:GetMouse()
local clamps = {
xmin = math.rad(0),
xmax = math.rad(180),
ymin = math.rad(-30),
ymax = math.rad(30),
zmin = math.rad(-60),
zmax = math.rad(60),
}
script.Parent.Equipped:Connect(function()
local char = Player.Character
if char:FindFirstChild('RightUpperArm') then
origRightS = char.RightUpperArm:WaitForChild('RightShoulder').C0
end
if char:FindFirstChild('Head') then
origNeck = char.Head:WaitForChild("Neck").C0
end
renderconnec = game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
local lerpSpeed = 10/(1/deltaTime)
local cframe = CFrame.new(char.UpperTorso.Position, mouse.Hit.Position) * CFrame.Angles(math.pi/2, 0, 0)
if char:FindFirstChild('RightUpperArm') then
local x,y,z = (CFrame.new(char.RightUpperArm.RightShoulder.C0.Position) * char.UpperTorso.CFrame:toObjectSpace(cframe)):ToEulerAnglesXYZ()
local cf2 = CFrame.new(char.RightUpperArm.RightShoulder.C0.Position) * CFrame.Angles(math.clamp(x,clamps.xmin,clamps.xmax),math.clamp(y,clamps.ymin,clamps.ymax),math.clamp(z,clamps.zmin,clamps.zmax))
char.RightUpperArm.RightShoulder.C0 = char.RightUpperArm.RightShoulder.C0:Lerp(cf2 * CFrame.Angles(math.rad(-90),0,0),lerpSpeed)
end
if char:FindFirstChild('Head') then
local x,y,z = (CFrame.new(char.Head.Neck.C0.Position) * char.UpperTorso.CFrame:toObjectSpace(cframe)):ToEulerAnglesXYZ()
local cf2 = CFrame.new(char.Head.Neck.C0.Position) * CFrame.Angles(math.clamp(x,clamps.xmin,clamps.xmax),math.clamp(y,clamps.ymin,clamps.ymax),math.clamp(z,clamps.zmin,clamps.zmax))
char.Head.Neck.C0 = char.Head.Neck.C0:Lerp(cf2 * CFrame.Angles(math.rad(-90),0,0),lerpSpeed)
end
end)
end)
script.Parent.Unequipped:Connect(function()
local char = Player.Character
if renderconnec then
renderconnec:Disconnect()
end
if char:FindFirstChild("RightUpperArm") then
char.RightUpperArm.RightShoulder.C0 = origRightS
end
if char:FindFirstChild('Head') then
char.Head.Neck.C0 = origNeck
end
end)