I've tried scripting a grab tool on my own. Seems to work when I tried testing in the Studio, doesn't work at all (bar the arm-moving part, which I copied from the Night At The Museum flashlight.)
Here are the scripts.
Server:
wait(0.4)
local Tool = script.Parent
local Handle = Tool:WaitForChild("Handle")
local Remote = Tool:FindFirstChild("Remote")
local Weld
local Motor
local MotorPart0
local MotorPart1
local GripParts = {}
local CertainPartsToGrab = {"Part", "Potato"} --Certin name of parts TO GRAB
local GrabListOn = false --Is this list functional? If true, then grabs ONLY parts with names in this bracket and nothing else
local CertainPartsToIgnore = {"Baseplate", "Capitalism"} --Certin name of parts TO IGNORE
local IgnoreListOn = true --Is this list functional? If true, then grabs EVERYTHING ELSE except parts in this bracket
local PartRange = 5 --How far away from the torso can the part be grabbed (in studs)
local GrabbedPart
print ("ok")
function getPlayer()
return game:GetService("Players"):GetPlayerFromCharacter(Tool.Parent)
end
function setPointDirection(position)
local char = Tool.Parent
if not char then return end
if not Weld then
Motor = char.Torso["Right Shoulder"]:Clone()
MotorPart0 = char.Torso
MotorPart1 = char["Right Arm"]
Weld = Instance.new("Weld")
Weld.Part0 = char.Torso
Weld.Part1 = char["Right Arm"]
Weld.C0 = CFrame.new(1, 1, 0)
Weld.Parent = Weld.Part0
end
local jointPosition = Weld.Part0.CFrame:toWorldSpace(CFrame.new(1.5, 0.5, 0))
local cframe = CFrame.new(jointPosition.p, position) * CFrame.Angles(math.pi/2, 0, 0) * CFrame.new(0, -0.5, 0)
Weld.C0 = Weld.Part0.CFrame:toObjectSpace(cframe)
end
function MouseDown(Mouse, Character, Torso, RArm)
print("MouseDown server fire")
local GrabListPass = false
local IgnoreListPass = false
local RayBeam = Ray.new(Torso.CFrame.p, (Mouse.Hit.p - Torso.CFrame.p).unit * 300)
local RayHitPart, RayHitPos = game.Workspace:FindPartOnRay(RayBeam, Character, false, false)
local Distance = (Torso.CFrame.p - RayHitPos).magnitude
if GrabListOn == true then
for _, Name in pairs (CertainPartsToGrab) do
if tostring(Name) == RayHitPart.Name then
GrabListPass = true
break
elseif tostring(Name) ~= RayHitPart.Name then
GrabListPass = false
end
end
elseif GrabListOn == false then
GrabListPass = true
end
if IgnoreListOn == true then
for _, Name in pairs (CertainPartsToIgnore) do
if tostring(Name) ~= RayHitPart.Name then
IgnoreListPass = true
elseif tostring(Name) == RayHitPart.Name then
IgnoreListPass = false
break
end
end
elseif IgnoreListOn == false then
IgnoreListPass = true
end
if GrabListPass == true and IgnoreListPass == true then
if Distance <= PartRange and Mouse.Target ~= nil then
GrabbedPart = Mouse.Target
local PosPartR = Instance.new("Part", game.Workspace)
PosPartR.CFrame = CFrame.new(RayHitPos)
PosPartR.Anchored = false
PosPartR.CanCollide = false
PosPartR.Size = Vector3.new(0.2, 0.2, 0.2)
PosPartR.Transparency = 1
local PartWeld = Instance.new("Weld", PosPartR)
PartWeld.Part0 = PosPartR
PartWeld.Part1 = RayHitPart
table.insert(GripParts, PosPartR)
local RPartAttach = Instance.new("Attachment", PosPartR)
RPartAttach.Position = Vector3.new(0, 0, 0)
RPartAttach.Name = "RightPartAttachment"
local RArmAttach = Instance.new("Attachment", RArm)
RArmAttach.Name = "RightArmAttachment"
RArmAttach.Position = Vector3.new(0, -1, 0)
local RBallCons = Instance.new("BallSocketConstraint", PosPartR)
RBallCons.Name = "RGripCons"
RBallCons.Attachment0 = RPartAttach
RBallCons.Attachment1 = RArmAttach
GrabbedPart.CanCollide = false
end
end
end
function MouseUp(RArm)
print("MouseUp server fire")
for _, Part in pairs (GripParts) do
Part:Destroy()
end
for _, Part in pairs (RArm:GetChildren()) do
if Part.Name == "RightArmAttachment" then
Part:Destroy()
end
end
if GrabbedPart then
GrabbedPart.CanCollide = true
GrabbedPart = nil
end
end
function onRemote(player, func, ...)
if player ~= getPlayer() then return end
if func == "UpdateDirection" then
setPointDirection(...)
end
if func == "MouseDown" then
MouseDown(...)
print("MouseDown remote fire")
end
if func == "MouseUp" then
MouseUp(...)
print("MouseUp remote fire")
end
end
function onEquipped()
Handle.Transparency = 1
end
function onUnequipped()
if Weld then
Weld:Destroy()
Weld = nil
end
if Motor then
Motor.Part0 = MotorPart0
Motor.Part1 = MotorPart1
Motor.Parent = MotorPart0
Motor = nil
end
Handle.Transparency = 0
for _, Part in pairs (GripParts) do
Part:Destroy()
end
local RArm = getPlayer().Character:FindFirstChild("Right Arm")
for _, Part in pairs (RArm:GetChildren()) do
if Part.Name == "RightArmAttachment" then
Part:Destroy()
end
end
end
Remote.OnServerEvent:connect(onRemote)
Tool.Equipped:connect(onEquipped)
Tool.Unequipped:connect(onUnequipped)
Local:
local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()
local Tool = script.Parent
local Remote = Tool:WaitForChild("Remote")
function onMouseMove()
Player = game:GetService("Players").LocalPlayer
Mouse = Player:GetMouse()
Remote:FireServer("UpdateDirection", Mouse.Hit.p)
end
function onMouseDown()
Player = game:GetService("Players").LocalPlayer
Mouse = Player:GetMouse()
local Character = Player.Character
local Torso = Character:FindFirstChild("Torso")
local RArm = Character:FindFirstChild("Right Arm")
Remote:FireServer("MouseDown", Mouse, Character, Torso, RArm)
print("MouseDown fire")
end
function onMouseUp()
Player = game:GetService("Players").LocalPlayer
local Character = Player.Character
local RArm = Character:FindFirstChild("Right Arm")
Remote:FireServer("MouseUp", RArm)
print("MouseUp fire")
end
Mouse.Move:connect(onMouseMove)
Mouse.Button1Down:connect(onMouseDown)
Mouse.Button1Up:connect(onMouseUp)
game:GetService("RunService").Heartbeat:connect(onMouseMove)
As I've mentioned before, the tool worked flawlessly in the local Studio test. It's broken when used in an actual game server.

2 comments
since the tool is in your player's backpack, you should be able to call the localplayer by using script.Parent.Parent.Parent[and so on] until you get the player, it should work with other variables after you use like, Player = script.Parent.Parent.Parent.Parent[say this gets to your player] then you can use local Mouse = Player:GetMouse() flawlessly.
Didn't work. Sorry :(