Faulty drag system

Made a drag system to make the player to be able to hold materials, but it can get quite faulty at times and I can’t see the root of the problem.


(2.6 MB)

Problem 1:
Significant delay between the object dropping and the player releasing their left click.

Problem 2:
Clickly clicking the left click would for whatever reason not register it being released, meaning it still thinks the user is still holding their left click.

Problem 3:
When quickly grabbing and releasing an object, the player can practically tower up.

Problem 4:
As seen in the video, some parts can go out flying even when released.

client-side
local request = game.ReplicatedStorage.interactions.requestControl
local lplr = game.Players.LocalPlayer
local mouse = lplr:GetMouse()
local keyboard = game:GetService("UserInputService")

local solids = workspace.Instances.Solids
local focusDistance = 6

local grabbed : BasePart? = nil
local line : LinearVelocity
local sParams = RaycastParams.new()
sParams.FilterType = Enum.RaycastFilterType.Include
sParams.FilterDescendantsInstances = {solids}

local lasttarget = Vector3.zero

local function onDown()
	local mouseray = workspace:Raycast(mouse.Origin.Position, mouse.Origin.LookVector * 50, sParams)
	if mouseray then
		if not grabbed then
			local allowed = request:InvokeServer(mouseray.Instance)
			if allowed then
				line = mouseray.Instance.line
				grabbed = mouseray.Instance
				focusDistance = (mouse.Origin.Position - mouseray.Position).Magnitude
			end
		end
	end
end

local function distanceRay()
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = {workspace.Instances, lplr.Character}
	local ray = workspace:Raycast(mouse.Origin.Position, mouse.Origin.LookVector * (focusDistance + 0.1), params)
	if ray then
		return ray.Position
	else
		return mouse.Origin.Position + mouse.Origin.LookVector * focusDistance
	end
end

local function onMove()
	if grabbed and line then
		lasttarget = distanceRay()
	end
end

local function onUp()
	if grabbed then
		request:InvokeServer(grabbed)
		grabbed = nil
		lasttarget = Vector3.zero
	end
end

mouse.Button1Down:Connect(onDown)
mouse.Button1Up:Connect(onUp)
mouse.Move:Connect(onMove)
workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):Connect(onMove)

mouse.WheelForward:Connect(function()
	focusDistance = math.min(27, focusDistance + 1.5)
end)

mouse.WheelBackward:Connect(function()
	focusDistance = math.max(3, focusDistance - 1.5)
end)

game["Run Service"].PreSimulation:Connect(function(dt)
	if grabbed and line and lasttarget.Magnitude > 0.1 then
		local origin : Vector3 = grabbed.Position

		local direction = (lasttarget-origin).Unit
		local distance = (origin-lasttarget).Magnitude

		local magnitude = direction * (distance / dt * 0.075)

		line.VectorVelocity = magnitude
	end
	if grabbed then
		grabbed.AssemblyAngularVelocity = Vector3.zero
	end
end)
Server-side
local fol = workspace.Instances.Solids
local rC = game.ReplicatedStorage.interactions.requestControl
local controlled = {}
rC.OnServerInvoke = function(plr, part)
	print(plr.Name.." attempts to control/release a part!")
	if controlled[plr] then
		controlled[plr].Owner.Value = nil
		controlled[plr]:SetNetworkOwner(nil)
		controlled[plr] = nil
		part.line.Enabled = false
		part:ApplyImpulse(part.line.VectorVelocity*3)
		part.CollisionGroup = "def"
		return false
	end
	if part then
		if part.Parent == fol then
			if part.Owner.Value == nil then
				part:SetNetworkOwner(plr)
				part.Owner.Value = plr
				part.line.Enabled = true
				controlled[plr] = part
				part.CollisionGroup = "cGroup"
				return true
			end
		end
	end
	return false
end

Anatomy of a part that can be grabbed by the player:
image

4 Likes

The MP4 file has for whatever reason lost most of its framrate after conversion, here’s the original recording file:
robloxapp-20240107-0853066.wmv (2.6 MB)

3 Likes

dragdetectors exist ya know -_-

2 Likes

Yeah and in the drag detector there are properties that you can change and adjust for your liking @coolalex1835

Are you sure that’s the right solution? All I found for DragDetectors is that they allow movement in x and z direction, but not y. So you can open doors etc. but not “pick up” something. How would you do that with the DragDetector? Like in all these examples Drag Detectors | Documentation - Roblox Creator Hub they are all dragged in x and y direction only.

1 Like

Doesn’t drag detectors have all directions x, y, z?

image
There are many settings that you can change.

I’m not sure though.

It has, but I haven’t seen any features that would allow picking up stuff with it. ChatGPT also says:

The DragDetector in Roblox primarily detects dragging movements in the XZ plane. If you want the object to move in the Y-axis as well, you might need to resort to scripting to achieve that behavior.

If you find out otherwise, let us know :sweat_smile:

1 Like

This is not true, in this case ChatGPT was wrong, and in reality it literally has no limits with a 3D space (see here and here), in my opinion it’s just probably just not accurate with the camera changing.

As for sourcing AI in Roblox posts, you should either be using Google Bard or nothing IMO, since it’s the only public chatbot that is actually somewhat accurate when providing it with a link. ChatGPT is not meant to provide factual information, just talk like a human. Don’t get me wrong it, it does that very well and even better than Bard, but it’s just not reliable at all for sourcing information.

I asked Google Bard this prompt;

According to Drag Detectors | Documentation - Roblox Creator Hub Can you drag in a 3D environment/worldspace?

and it replied with this, which I reviewed and is all true and would agree with, along with some okayish code which I will not be including.


Hey, I’ve decided to fix the system with a better system (and i tested it ingame aswell, where it worked well).

A bit off-topic from original post, but how can I utilize my grab system for mobile users? For PC, I use a raycast @ the direction of the mouse, but since mobile users of course don’t have a mouse, I can just use taps.

However the simple nature that it would be less accurate to decide what part to select, do I use some other methods rather than raycasts? Possibly spherecasting? Or is there an existing solution for my problem?

Thanks!

They can be dragged on all axes, also don’t rely on information that ChatGPT makes up.

& also @cakeycocoa
You’re right in a sense that they can be dragged in 3D, e.g. pulled with your character etc., but, as far as I know, you cannot control it in 3D. The mouse only goes left and right, up and down, there’s no factor that controls it in 3D. I also tried out different modes and played around. While I can confirm that you are sort of right, there’s still much scripting to be done to control something with the dragging feature in 3D.
Also @cakeycocoa I don’t just take what ChatGPT writes, of course I do my own research and test the output. So far it was a very great help though :slight_smile:
But if you find a way to better control it in 3D, please let me know! I also tried to achieve that with as little scripting as possible and did not yet unfortunately.

How did you fix it? With what you wrote and then improved?

I made a very simple but effective drag system a few months ago. You’re welcome to have a look at the code and see if there is anything you want to take :slight_smile:

Post

… of course I do my own research and test the output. So far it was a very great help though :slight_smile:

It wasn’t really that great of a help, everything in the quote was proven wrong. Life is about learning though :slight_smile: