Dragging System: How to make it work with models?

Hello! I’m currently working on a dragging system, similiar to the one in Lumber Tycoon 2. It works fine, however, I want it to work with models. I tried doing some stuff with the PrimaryPart but it didn’t seem to work. How could I do this?

Server
-- GrabServer
-- 11/3/21
-- lilsquish08

local TAG_NAME = "Grabbable"

local collectionService = game:GetService("CollectionService")
local parts = collectionService:GetTagged(TAG_NAME)

local playerParts = {}

function RequestGrab (player, part)
	if playerParts[player] then return false end

	if  not collectionService:HasTag(part, TAG_NAME) then
		return false
	end
	
	local bp = Instance.new("BodyPosition")
	local bg = Instance.new("BodyGyro")
	
	bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
	bp.D = 900
	bp.Position = part.Position
	bp.Parent = part
	
	bg.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
	bg.CFrame = part.CFrame
	bg.Parent = part
	
	part:SetNetworkOwner(player)
	playerParts[player] = part
	return true
end

function StopGrab (player, part)
	if playerParts[player] ~= part then return false end
	
	part.BodyPosition:Destroy()
	part.BodyGyro:Destroy()
	
	playerParts[player] = nil
end

game.ReplicatedStorage.RequestGrab.OnServerInvoke = RequestGrab
game.ReplicatedStorage.StopGrab.OnServerEvent:Connect(StopGrab)

game.Players.PlayerRemoving:Connect(function(player)
	if playerParts[player] then
		StopGrab(player, playerParts[player])
	end
end)
Client
-- GrabClient
-- 11/3/21
-- lilsquish08

local UserInputService = game:GetService("UserInputService")

local TAG_NAME = "Grabbable"

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local head = character:WaitForChild("Head")

local requestGrab = game.ReplicatedStorage.RequestGrab
local stopGrab = game.ReplicatedStorage.StopGrab

local trackingPart = nil
local heartbeat

local grabDistance = 10

function UpdateTrackingPart ()
	local position = head.Position + (mouse.Hit.Position - head.Position).Unit * 6
	
	trackingPart.BodyPosition.Position = position
end

function MouseDown ()
	local target = mouse.Target
	
	if target then
		local distanceFromTarget = (humanoidRootPart.Position - target.Position).Magnitude
		
		if distanceFromTarget < grabDistance then
			if target and requestGrab:InvokeServer(target) then
				trackingPart = target
				heartbeat = game:GetService("RunService").Heartbeat:Connect(UpdateTrackingPart)
				
				print("Player started grabbing")
			end
		end
	end
end

function MouseUp ()
	if not trackingPart then return end
	stopGrab:FireServer(trackingPart)
	trackingPart = nil
	heartbeat:Disconnect()
	
	print("Player stopped grabbing")
end

function CharacterAdded (character)
	mouse.TargetFilter = character
end

UserInputService.InputBegan:Connect(function(inputObject, processed)
	if processed then return end
	if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
		MouseDown()
	end
end)

UserInputService.InputEnded:Connect(function(inputObject, processed)
	if processed then return end
	if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
		MouseUp()
	end
end)

CharacterAdded(player.Character or player.CharacterAdded:Wait())
player.CharacterAdded:Connect(CharacterAdded)

Is the model anchored or locked? If it is, then unanchor or unlock it.

Maybe try using

model:MoveTo(x,y,z)

Remember to set the PrimaryPart first so it works.

The model is not locked and cannot be anchored since I need to set network ownership on the part that is being dragged.

1 Like

I’m not sure if this would work considering I am using a BodyGyro and BodyPosition for the part movement. I could be wrong though.

1 Like

Maybe this might work:
Make an invisible part in the middle of the model,
Weld all the parts in the model to one another (rip it off from qperfection weld or somthing else),
Use the invisible part to move the model,
Once done, destroy all the welds and delete the invisible part.

https://developer.roblox.com/en-us/api-reference/function/Model/SetPrimaryPartCFrame
https://developer.roblox.com/en-us/api-reference/function/Model/MoveTo

These 2 functions should help you.

Did you try using Pivot Points?

Never looked into it. I’m currently having trouble trying to implement the solutions above into my code.

Well, I solved the issue, and gosh you don’t wanna know how dumb I am. Maybe I need a break.

All I needed to do was tag the parts in the model Grabbable and now it works like a charm. Thanks everyone for the help!

:rofl::rofl::rofl:

1 Like