What do you want to achieve? Keep it simple and clear!
I want the arm to be able to point towards the mouse, and you are only limited to pointing it forwards, the left and right to some extent, but not to the back of you.
What is the issue? Include screenshots / videos if possible!
The player’s right arm is not doing what I want it to do. I believe it might be because it was rotated because of the weld that was created or something.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I tried changing things in my script but it did not seem to work. I had used code I found on the DevForum and I though I do understand what some things in the code do, I don’t understand it fully because I am pretty much a beginner at Lua.
Here is my code:
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local X_MIN_DEG = 15
local X_MAX_DEG = 145
local Z_MIN_DEG = -30
local Z_MAX_DEG = 30
local plr = Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local mouse = plr:GetMouse()
local tool = script.Parent
local radLimits = {
math.rad(X_MIN_DEG),
math.rad(X_MAX_DEG),
math.rad(Z_MIN_DEG),
math.rad(Z_MAX_DEG)
}
local function rotateArm()
local hrp = char:WaitForChild("HumanoidRootPart")
local rShoulder = char:WaitForChild("Torso"):WaitForChild("Right Shoulder")
local mouseHit = mouse.Hit
local mouseHitPos = mouseHit.Position
local jointDefaultCfWorldSpace = rShoulder.Part0.CFrame*rShoulder.C0
local jointTargetCfWorldSpace = CFrame.new(jointDefaultCfWorldSpace.Position, mouseHitPos)*CFrame.Angles(math.pi/2, 0, 0)
-- transform angles
local dir = (mouseHitPos-jointDefaultCfWorldSpace.Position).Unit
local x = math.abs(dir.Y*math.pi/2+math.pi/2)
local z = math.atan2(dir.Z, dir.X)-math.atan2(jointDefaultCfWorldSpace.LookVector.Z, jointDefaultCfWorldSpace.LookVector.X)
x = math.clamp(x, radLimits[1], radLimits[2])
z = math.clamp(z, radLimits[3], radLimits[4])
rShoulder.Transform = CFrame.Angles(x, 0, z)
end
local steppedConn
tool.Equipped:Connect(function()
steppedConn = RunService.Stepped:Connect(function()
rotateArm(char)
end)
end)
tool.Unequipped:Connect(function()
steppedConn:Disconnect()
end)
I think the math will be easier if you just move the mouse into joint space instead of moving every else into world space.
I didn’t test this, but it should give the general idea:
local function rotateArm()
local hrp = char:WaitForChild("HumanoidRootPart")
local rShoulder = char:WaitForChild("Torso"):WaitForChild("Right Shoulder")
local jointDefaultCfWorldSpace = rShoulder.C0:ToWorldSpace(rShoulder.Part0.CFrame)
local mouseRelativeToShoulder = mouse.Hit:ToObjectSpace(jointDefaultCfWorldSpace)
local dir = mouseRelativeToShoulder.Position - rShoulder.C0.Position
-- now that everything's in object space you can imagine that the joint
-- is sitting at 0,0,0 facing the -Z axis
-- yaw or pitch of 0 means "straight in front"
local yaw = math.atan2(-dir.Z, dir.X) -- left/right rotation
local pitch = math.atan2(dir.Y, -dir.Z) -- up/down rotation
-- todo: figure out clamping
-- note: CFrame.Angles applies rotations in Z, Y, X order.
-- CFrame.fromOrientation applies in Y, X, Z order.
rShoulder.Transform = CFrame.fromOrientation(yaw, 0, pitch + math.pi/2)
end
You might also want to experiment with CFrame:ToOrientation. Might give you a shortcut.
It’s still letting you point to the back of yourself. I’m sure this works by tweaking the code a bit.
Also, I don’t really know how to use CFrame all that well, though I get what it does.
Had to futz with the axes a lil to get it to work but:
There’s probably a better way to go about this, also, but oh well
local YAW_MIN = math.rad(-70) -- left/right (up to +/-180)
local YAW_MAX = math.rad(70)
local PITCH_MIN = math.rad(-30) -- up/down (up to +/-90)
local PITCH_MAX = math.rad(30)
local function rotateArm()
local hrp = char:WaitForChild("HumanoidRootPart")
local rShoulder = char:WaitForChild("Torso"):WaitForChild("Right Shoulder")
-- jointWorld is the position of C0 with the rotation of C0*C1:
local jointWorld = rShoulder.Part0.CFrame * rShoulder.C0
-- joint->mouse vector in "joint space"
local dirLocal = jointWorld:PointToObjectSpace(mouse.Hit.Position)
-- yaw or pitch of 0 means "straight in front"
local yaw = math.atan2(-dirLocal.Z, dirLocal.X) -- left/right rotation
local pitch = math.asin(dirLocal.Unit.Y) -- up/down rotation (use above to make a triangle with the Y axis)
local yawClamped = math.clamp(yaw, YAW_MIN, YAW_MAX)
local pitchClamped = math.clamp(pitch, PITCH_MIN, PITCH_MAX)
-- note: CFrame.Angles applies rotations in Z, Y, X order
-- CFrame.fromOrientation applies in Y, X, Z order
rShoulder.Transform = CFrame.fromOrientation(0, yawClamped, pitchClamped + math.pi/2)
end