Help with drag system

Recently i tried to make a drag system like the one in dead rails by following a bit of this tutorial,
Click & Drag Objects - Dead Rails Tutorial #4 - YouTube, i tried it myself and for some confusing reason it doesn’t work, it’s not because of the network ownership but i figured it had something to do w/ the attachments and align positions but i can’t figure that out.

Here’s a footage of the system

CLIENT

local STRING_TAG = "Draggable"
local MAX_DISTANCE = 25

local currentTarget = nil
local currentObject = nil

local dragAtt = workspace.Terrain:WaitForChild("DragAttachment")
local dragRequest = game.ReplicatedStorage:WaitForChild("DragRequest")

local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")
local player = game.Players.LocalPlayer

local partHighlight = script:FindFirstChild("Highlight")
if not partHighlight then
	partHighlight = Instance.new("Highlight")
	partHighlight.Parent = player:WaitForChild("PlayerGui")
end

script.AlignOrientation.Attachment1 = dragAtt
script.AlignPosition.Attachment1 = dragAtt

local function dropObject()
	if currentObject then
		dragRequest:InvokeServer(currentObject, false)
	end
	currentObject = nil
	script.AlignOrientation.Attachment0 = nil
	script.AlignPosition.Attachment0 = nil
end

UIS.InputBegan:Connect(function(input, gp)
	if gp then return end
	if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
	if currentTarget and not currentObject then

		currentObject = currentTarget
		local partAtt = currentObject:FindFirstChild("PartAttachment")
		if not partAtt then
			partAtt = Instance.new("Attachment")
			partAtt.Name = "PartAttachment"
			partAtt.Parent = currentObject
		end

		local result = dragRequest:InvokeServer(currentObject, true)
		if result then
			script.AlignOrientation.Attachment0 = partAtt
			script.AlignPosition.Attachment0 = partAtt
		else
			currentObject = nil
		end
	else
		dropObject()
	end
end)

UIS.InputEnded:Connect(function(input, gp)
	if gp then return end
	if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
	dropObject()
end)

RunService.RenderStepped:Connect(function()
	if currentObject then
		local partAtt = currentObject:FindFirstChild("PartAttachment")
		if not partAtt then
			partAtt = Instance.new("Attachment")
			partAtt.Name = "PartAttachment"
			partAtt.Parent = currentObject
		end
		script.AlignOrientation.Attachment0 = partAtt
		script.AlignPosition.Attachment0 = partAtt

		local attPosition = workspace.CurrentCamera.CFrame * CFrame.new(0,0,-5)
		dragAtt.CFrame = attPosition
	else
		local mousePosition = UIS:GetMouseLocation()
		local ray = workspace.CurrentCamera:ViewportPointToRay(mousePosition.X, mousePosition.Y)

		local rayParams = RaycastParams.new()
		rayParams.FilterType = Enum.RaycastFilterType.Include
		rayParams.FilterDescendantsInstances = CollectionService:GetTagged(STRING_TAG)

		local raycast = workspace:Raycast(ray.Origin, ray.Direction * MAX_DISTANCE, rayParams)

		if raycast and raycast.Instance then
			partHighlight.Adornee = raycast.Instance
			currentTarget = raycast.Instance
		else
			partHighlight.Adornee = nil
			currentTarget = nil
		end
	end
end)

SERVER

local remote = game.ReplicatedStorage:WaitForChild("DragRequest")

remote.OnServerInvoke = function(player, object, requestingPickup)

	if requestingPickup and not object:GetAttribute("dragOwner") then
		object:SetAttribute("dragOwner", player.UserId)
		object:SetNetworkOwner(player)
		return true

	elseif not requestingPickup and object:GetAttribute("dragOwner") == player.UserId then
		object:SetAttribute("dragOwner", nil)
		object:SetNetworkOwnershipAuto()
		return true
	end

	return false
end

Any type of help will be appreciated, thanks in advance!

1 Like

dont know if you want exactly your system but roblox offers an instance called Drag Detector

made basically what you wanted but with one instance and just changing the DragStyle property to the TranslateViewPlane option so that the “drag plane” the part tries to move is always facing the camera. There are a lot of other properties in it for you to play around.

draggable part.rbxm (4.7 KB)

1 Like

sorry, i already thought of using dragdetectors although they aren’t well suited for my game cause i want to add in custom properties that dragdetectors wouldn’t really be able to support, but thanks for the suggestion

the error was not parenting the body movers to the part youre moving, i presume they dont work either if theyre not parented to the object theyre moving or they dont work if they arent in the workspace

CLIENT:

local STRING_TAG = "Draggable"
local MAX_DISTANCE = 25

local currentTarget = nil
local currentObject = nil

local terrain = workspace:WaitForChild("Terrain")
local dragAtt = terrain:WaitForChild("DragAttachment")
local dragRequest = game.ReplicatedStorage:WaitForChild("DragRequest")

local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")
local player = game.Players.LocalPlayer

local partHighlight = script:FindFirstChild("Highlight")
if not partHighlight then
	partHighlight = Instance.new("Highlight")
	partHighlight.Parent = player:WaitForChild("PlayerGui")
end

local alignPosition = script.AlignPosition
local alignOrientation = script.AlignOrientation

alignPosition.Attachment1 = dragAtt
alignOrientation.Attachment1 = dragAtt

local function dropObject()
	if currentObject then
		dragRequest:InvokeServer(currentObject, false)
	end
	currentObject = nil
	alignPosition.Attachment0 = nil
	alignOrientation.Attachment0 = nil
end

UIS.InputBegan:Connect(function(input, gp)
	if gp then return end
	if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
	if currentTarget and not currentObject then

		currentObject = currentTarget
		local partAtt = currentObject:FindFirstChild("PartAttachment")
		if not partAtt then
			partAtt = Instance.new("Attachment")
			partAtt.Name = "PartAttachment"
			partAtt.Parent = currentObject
		end

		local result = dragRequest:InvokeServer(currentObject, true)
		if result then
			alignPosition.Attachment0 = partAtt
			alignOrientation.Attachment0 = partAtt
		else
			currentObject = nil
		end
	else
		dropObject()
	end
end)

UIS.InputEnded:Connect(function(input, gp)
	if gp then return end
	if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
	dropObject()
end)

RunService.RenderStepped:Connect(function()
	if currentObject then
		local partAtt = currentObject:FindFirstChild("PartAttachment")
		if not partAtt then
			partAtt = Instance.new("Attachment")
			partAtt.Name = "PartAttachment"
			partAtt.Parent = currentObject
		end
		
		alignPosition.Attachment0 = partAtt
		alignOrientation.Attachment0 = partAtt
		
		alignPosition.Parent = currentObject
		alignOrientation.Parent = currentObject

		local attPosition = workspace.CurrentCamera.CFrame * CFrame.new(0,0,-5)
		dragAtt.CFrame = attPosition
	else
		local mousePosition = UIS:GetMouseLocation()
		local ray = workspace.CurrentCamera:ViewportPointToRay(mousePosition.X, mousePosition.Y)

		local rayParams = RaycastParams.new()
		rayParams.FilterType = Enum.RaycastFilterType.Include
		rayParams.FilterDescendantsInstances = CollectionService:GetTagged(STRING_TAG)

		local raycast = workspace:Raycast(ray.Origin, ray.Direction * MAX_DISTANCE, rayParams)
		
		alignPosition.Parent = script
		alignOrientation.Parent = script

		if raycast and raycast.Instance then
			partHighlight.Adornee = raycast.Instance
			currentTarget = raycast.Instance
		else
			partHighlight.Adornee = nil
			currentTarget = nil
		end
	end
end)
1 Like

No, .. it doesn’t, just the attachments that need to be a direct children of a part.

what do you mean? yours doesnt work? or you want the body movers to remain under the script?

1 Like

Wow, i really didn’t know why mine doesn’t work… (i already tried with the movers under the hovered part but doesn’t work correctly)
Could you try it w/ the movers under the script?

i just created a localscript in ReplicatedFirst for the local part
and one in serverScriptService for the server
created a dragAttachment in the terrain
and just created a AlignPosition and AlignOrientation under the local script

Will it still work if i don’t parent the movers directly to the part and just let it stay parented to the local script?

no this wont work because the movers need to be inside the workspace where the part is to work

1 Like

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