Part Dragging System (MOBILE SUPPORT)

Just to be clear I’m aiming for something like this, preferably just 1:1.

Apologies for the streamable, file was too large to upload.

It’s gonna take a little bit of time to make that script.
Hope you don’t mind the waiting, I will take a little long.

But I think I can make that.
Also, did the last script work? Can you show the result? With it unanchored
Also mantain the part unanchored because the video you showed shows all parts unanchored

All parts were and have been unanchored, tool didn’t seem to make a difference.

I can wait aswell, dw.
In the meantime I’ll also try to replicate the video, see what type of result i get.

I’m making more than one script because I’m unsure if they work as you intended.
Here’s the first. This one is only an update from the other one, but ‘1:1’, like you asked:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
local runService = game:GetService("RunService")
local uis = game:GetService("UserInputService")

local character = player.Character or player.CharacterAdded:Wait()
local root = character:WaitForChild("HumanoidRootPart")

local dragging = false
local draggedPart = nil

local maxDistance = 15
local holdOffset = Vector3.new(0, 0, -8)

local function getHoldPosition()
	return root.Position + root.CFrame:VectorToWorldSpace(holdOffset)
end

local function getDraggablePart()
	local ray = Ray.new(camera.CFrame.Position, (mouse.Hit.p - camera.CFrame.Position).Unit * maxDistance)
	local part = workspace:FindPartOnRay(ray, character)
	return part
end

local function beginDrag(part)
	dragging = true
	draggedPart = part
	if draggedPart:IsA("BasePart") then
		draggedPart:SetNetworkOwner(player)
		local bodyPos = Instance.new("BodyPosition")
		bodyPos.MaxForce = Vector3.new(400000, 400000, 400000)
		bodyPos.D = 10
		bodyPos.P = 10000
		bodyPos.Parent = draggedPart
		draggedPart.BodyPosition = bodyPos
	end
end

local function endDrag()
	dragging = false
	draggedPart = nil
end

mouse.Button1Down:Connect(function()
	local part = getDraggablePart()
	if part then
		beginDrag(part)
	end
end)

mouse.Button1Up:Connect(endDrag)

uis.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.Touch then
		endDrag()
	end
end)

runService.RenderStepped:Connect(function()
	if dragging and draggedPart then
		local desiredPosition = getHoldPosition()
		local direction = (mouse.Hit.p - desiredPosition)
		local targetPosition = desiredPosition + direction.Unit * math.min(direction.Magnitude, maxDistance)

		draggedPart.BodyPosition.Position = targetPosition
	end
end)

1 Like

I see ill give this a go
3.0.c.h.a.r.s

Just to update aswell, i wouldnt worry about the mobile support yet either, ill figure that out on my end

1 Like

BodyPosition is not a valid member of Part "Workspace.Blocks.Default" -
L68

Also do you mind adding if not part:IsDescendantOf(workspace.Blocks) then return end check into the code aswell

1 Like

Sorry for late response.
I forgot to mention that you need to add a BodyPosition to the part!

Here it’s:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
local runService = game:GetService("RunService")
local uis = game:GetService("UserInputService")

local character = player.Character or player.CharacterAdded:Wait()
local root = character:WaitForChild("HumanoidRootPart")

local dragging = false
local draggedPart = nil

local maxDistance = 15
local holdOffset = Vector3.new(0, 0, -8)

local function getHoldPosition()
	return root.Position + root.CFrame:VectorToWorldSpace(holdOffset)
end

local function getDraggablePart()
	local ray = Ray.new(camera.CFrame.Position, (mouse.Hit.p - camera.CFrame.Position).Unit * maxDistance)
	local part = workspace:FindPartOnRay(ray, character)
	return part
end

local function beginDrag(part)
	dragging = true
	draggedPart = part
	if draggedPart:IsA("BasePart") then
		if not part:IsDescendantOf(workspace.Blocks) then return end
		draggedPart:SetNetworkOwner(player)
		local bodyPos = Instance.new("BodyPosition")
		bodyPos.MaxForce = Vector3.new(400000, 400000, 400000)
		bodyPos.D = 10
		bodyPos.P = 10000
		bodyPos.Parent = draggedPart
		draggedPart.BodyPosition = bodyPos
	end
end

local function endDrag()
	dragging = false
	draggedPart = nil
end

mouse.Button1Down:Connect(function()
	local part = getDraggablePart()
	if part then
		beginDrag(part)
	end
end)

mouse.Button1Up:Connect(endDrag)

uis.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.Touch then
		endDrag()
	end
end)

runService.RenderStepped:Connect(function()
	if dragging and draggedPart then
		local desiredPosition = getHoldPosition()
		local direction = (mouse.Hit.p - desiredPosition)
		local targetPosition = desiredPosition + direction.Unit * math.min(direction.Magnitude, maxDistance)

		draggedPart.BodyPosition.Position = targetPosition
	end
end)

Gotcha ill give it a go when im back in studio, thank you

You don’t need to add a BodyPosition already. The script creates it. But if you want to create it manually, you’re free!

1 Like

Any news? Did it work? If not, tell me right away and I will help with that