I wanted to make a flashlight tool, but I didn’t know the script that the arm points to the mouse, so I looked around, but they pointed to the mouse from start to finish, and the arm The range of motion was also unrestricted.
What kind of script should I use to point the mouse only when I have the tool and limit the range of motion of my arm? Thank you.
I haven’t tested this, but try calling rotateArm
on RunService.Stepped
and give it the RightShoulder
Motor6D
. If Transform
isn’t updated on Stepped
, the changes will be overwritten by animations. You could use Tool.Equipped
to detect when the tool is equipped. Then create a Stepped
connection and store the Stepped
connection in a variable. Disconnect the Stepped
connection when the tool is unequipped (use Tool.UnEquipped
for this).
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
-- Replace the limits with your own values.
local X_MIN_DEG = -180
local X_MAX_DEG = 180
local Y_MIN_DEG = -180
local Y_MAX_DEG = 180
local Z_MIN_DEG = -180
local Z_MAX_DEG = 180
local plr = Players.LocalPlayer
local mouse = plr:GetMouse()
local radLimits = {
math.rad(X_MIN_DEG),
math.rad(X_MAX_DEG),
math.rad(Y_MIN_DEG),
math.rad(Y_MAX_DEG),
math.rad(Z_MIN_DEG),
math.rad(Z_MAX_DEG)
}
local function rotateArm(joint)
local jointDefaultCfWorldSpace = joint.Part0.CFrame*joint.C0
local jointTargetCfWorldSpace = CFrame.new(jointDefaultCfWorldSpace.Position, mouse.Hit.Position)
-- transform angles
local x, y, z = (jointDefaultCfWorldSpace:Inverse()*jointTargetCfWorldSpace):ToEulerAnglesXYZ()
x = math.clamp(x, radLimits[1], radLimits[2])
y = math.clamp(y, radLimits[3], radLimits[4])
z = math.clamp(z, radLimits[5], radLimits[6])
joint.Transform = CFrame.Angles(x, y, z)
end
Edit: You’re right, @WaterJamesPlough, I’ve fixed that now
Just noticed a mistake in the script, y and z variables should be these instead, I believe:
y = math.clamp(y, radLimits[3], radLimits[4]
z = math.clamp(z, radLimits[5], radLimits[6]
I got a error from this : [ToEulerAnglesXYZ is not a valid member of Vector3]
What should I do?
Edit : I fixed with using “fromEulerAnglesXYZ”.
but another error I got : [Argument 3 missing or nil]
I had forgotten to write CFrame.new() on one line. Does it now work?
I checked using RunService.RenderStepped:Connect(rotateArm(plr.Character.RightUpperArm.RightShoulder))
, but I got the error “Attempt to connect failed: Passed value is not a function”.
So it means “No.”
RunService.RenderStepped:Connect(rotateArm(plr.Character.RightUpperArm.RightShoulder))
Passes the return value of rotateArm
as the argument to the Connect
method. It returns nothing, so that value is nil. Try this instead.
RunService.Stepped:Connect(function()
rotateArm(plr.Character.RightUpperArm.RightShoulder)
end)
Remember to use Stepped
instead of RenderStepped
, it’s important when updating Transform
.
What should I say … It’s strange.
Since it is difficult to say by mouth, I will attach an image.
also a video
This works better. Not properly, though. The arm rotation doesn’t work properly when mouse.Hit.Position
is behind the character. I don’t know how to fix it.
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
-- Replace the limits with your own values.
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 mouse = plr:GetMouse()
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(char)
local hrp = char:WaitForChild("HumanoidRootPart")
local rShoulder = char:WaitForChild("RightUpperArm"):WaitForChild("RightShoulder")
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
Thank you very much. It worked.
This is the last question, but how do I enable it when I have the tool and restore it when I don’t have the tool?
I’m sorry to ask many questions.
local steppedConn
tool.Equipped:Connect(function()
steppedConn = RunService.Stepped:Connect(function()
updateArm(char)
end)
end)
tool.Unequipped:Connect(function()
steppedConn:Disconnect()
end)