Part Grab script

im working on a simple grabbing object script but there is a weird bug that i cant fix
whenever i pick the part up it just sort of flies slowly towards my screen while its also clipped to my cursor

server script

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local GrabEvent = Instance.new("RemoteEvent", ReplicatedStorage)
GrabEvent.Name = "GrabEvent"

local UpdatePositionEvent = Instance.new("RemoteEvent", ReplicatedStorage)
UpdatePositionEvent.Name = "UpdatePositionEvent"

local PlaceObjectFunction = Instance.new("RemoteFunction", ReplicatedStorage)
PlaceObjectFunction.Name = "PlaceObjectFunction"

local function onGrabRequest(player, part)
	if part and part:IsA("BasePart") then
		part.Anchored = false
		part.CanCollide = false
		part:SetNetworkOwner(player)
	end
end

local function onReleaseRequest(player, part, mousePosition)
	if part and part:IsA("BasePart") then
		part.Anchored = true  -- Anchor first to avoid intermediate physics calculations
		part.Position = mousePosition
		part:SetNetworkOwner(nil)
		wait(0.1)  -- Small delay to let the position update
		part.CanCollide = true
	end
end

GrabEvent.OnServerEvent:Connect(function(player, action, part)
	if action == "grab" then
		onGrabRequest(player, part)
	end
end)

UpdatePositionEvent.OnServerEvent:Connect(function(player, part, mousePosition)
	if part and part:IsA("BasePart") then
		part.Position = mousePosition
		UpdatePositionEvent:FireAllClients(part, mousePosition)
	end
end)

PlaceObjectFunction.OnServerInvoke = function(player, part, mousePosition)
	if part and part:IsA("BasePart") then
		onReleaseRequest(player, part, mousePosition)
	end
	return true
end

Local script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GrabEvent = ReplicatedStorage:WaitForChild("GrabEvent")
local UpdatePositionEvent = ReplicatedStorage:WaitForChild("UpdatePositionEvent")
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local grabbedObject = nil
local holding = false

local function grabObject(object)
	grabbedObject = object
	holding = true
	GrabEvent:FireServer("grab", object)
end

local function releaseObject()
	if grabbedObject then
		GrabEvent:FireServer("release", grabbedObject)
		grabbedObject = nil
		holding = false
	end
end

mouse.Button1Down:Connect(function()
	if holding then
		releaseObject()
	else
		local target = mouse.Target
		if target and target:IsA("BasePart") and target:FindFirstChildOfClass("ClickDetector") then
			grabObject(target)
		end
	end
end)

game:GetService("RunService").RenderStepped:Connect(function()
	if holding and grabbedObject then
		local mousePosition = mouse.Hit.p
		grabbedObject.Position = mousePosition
		UpdatePositionEvent:FireServer(grabbedObject, mousePosition)
	end
end)

UpdatePositionEvent.OnClientEvent:Connect(function(part, mousePosition)
	if part then
		part.Position = mousePosition
	end
end)

You should set mouse.TargetFilter to grabbedObject to fix your issue, so that the part doesn’t constantly move to its edge.

Are Drag Detectors | Documentation - Roblox Creator Hub of any use to you?

I never knew you had so much control with this method of grabbing physics, i tried avoiding it thinking that i lack control over what i can script in parallel with it. Thanks!

1 Like

No worries. They’re actually quite new too!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.