Announcing DragDetectors!

uh something like this?
b4d556938b114c37e5787e756c43c00668e99a6e (1)

4 Likes

@IceCreamPickels Ah, yes.

I think something like that should be fine!

Because it’s all in the same game view. You’ should be able to put DragDetectors beneath the swords and then to get them to ‘drop’ into nicely organized locations of the surrounding frame, you’d probably add a dragEnd callback that , when you let go, updates the object to go to a nice even position on your grid.

2 Likes

Thanks for the mention in the opening credits!

I tried out setting enabled = false, then immediately true afterwards for the cases I wanted to prevent dragging and this seems to work when coupled with simply returning nil in the DragStyleFunction. If I did not return nil, the player could still drag things for a moment each time they tried. I think this should be documented if this is going to be the canonical way to do this. There was no mention of being able to return nil in this function, nor is the quick disable/enable an obvious way to cancel a drag.

4 Likes

Thanks @PeZsmistic
In the coming weeks I’m going to work with documentation to add some of the information and techniques we’re discussing here to the DragDetectors Use Guide Page. We’ll get this in there.

2 Likes

Hello! I tried out the Lift and Carry game to see how it all worked out, and noticed it’s noticeably laggy/choppy from what presumably is changes in network ownership. It’s not a major obstacle for me, but I thought I’d point it out.

2 Likes

Thanks, @PysephDEV
There could be several things contributing to what you’ve observed, but I think it’s just one: a timing mismatch between the rate of view change and the timing at which we process drag events.

In this demo, we have both the Green one that moves “geometric style” versus the purple one which moves “physical style”.

The first thing that might feel like a lag or jump happens when you first click down on either block.
It jumps so that the center of the box is below the mouse. This has been reported before, and could be fixed by updating the scripts to account for that offset when calculating the CFrame returned by the dragStyleFunctaion. I may fix that soonish, if I get a chance.

Now let’s talk about network ownership. You can see who has network ownership if you download the world and open in studio. Make sure you turn the studio setting “Are owners Shown” to true. Then when you run it you can see that the purple box’s outline changes color to your character’s color and it stays that way through the whole drag. For this one, the script requests and is granted network ownership from the server on mouse down and maintains it the whole time. I don’t see anything that looks laggy for the purple one. The green one sets the box anchored on mouse down and unanchored on mouseup, so I don’t think network ownership has anything to do with the problem here either.

But during the drag, the green one has a little stutter to it. We’re fairly sure this has to do with a kind of mismatch between the timing of redraws relative to our drag events. You can see the same thing if you just make an anchored block with a dragDetector under it, go into first person view on play, and rotate the camera. There’s a stuttery motion and the block doesn’t keep up.

I think this is the crux of your issue.

Note that the purple block doesn’t look stuttery, because it’s moved by forces that kind of smooth out that discontinuity in the desired locations that drive the force.

So if it’s just the stuttering issue, we are aware of it and hope to address it in time, but it’s not our top priority right now.

If you think something else is going on, please let us know.

4 Likes

The default DragStyles seem to allow to drag parts from any point (Like a corner or the edge of the part, not just from its center). However, I can’t seem to achieve the same effect with DragStyle set to Scriptable. Is it possible to get the same effect with Scriptable? It almost feels like there is an attachment in the default DragStyles that is being dragged or something.

2 Likes

TL;DR →
[1] set the maxTorque on the DragDetector to 0.
[2] make sure that applyAtCenterOfMass is the default value of false
[3] in your dragStart callback, set the pivotOffset to match the hitFrame:
dragDetector.DragStart:Connect(function(player, ray, viewFrame, hitFrame, clickedPart)
clickedPart.PivotOffset = clickedPart.CFrame:ToObjectSpace(hitFrame)
– your other custom code here.
end)

Fuller explanation:
When you use scriptable, we create both a translation constraint and a rotation constraint to try to match your object to the CFrame you return. If you set the maxTorque to 0, then no torque is applied to satisfy the rotational constraint, and only the translation constraint gets satisfied.

So this will re-introduce the rotational response you see in the TranslatePlane, TranslateLine, etc styles.

But even in this case, the forces move the object’s pivot to the desired spot and not the part you click on. By default the pivot’s going to be the center, and if you want to ‘dangle’ by the clicked point, you can fix that by moving the pivot of the part to the clicked location on dragStart, because the constraint will move the pivot to match your cursor. This can be done, in the dragStart callback, with the code snippet above. You might want to save this value and restore it during dragEnd as well.

I know this seems like a lot of work. We’ll look into maybe an API addition or change to make this easier. But in the meantime, the above should get you where you need to go.

I hope to add this as a third model in the lift and carry demo tomorrow

4 Likes

Sorry for the late response, for me yes I guess you could say it’s important to be able to drag myself. A while ago I had an idea for a game with zero scripts, not a big project just something fun as a challenge for me. With DragDetectors recently releasing I went back to that idea and was going to try and expand it by having a moveable character. I know it’s a pretty silly thing but that’s at least my reason.

And if you want a reasonable use case, it could be used as a gimmick movement system for an obby type game.

2 Likes

I’ll go ask around and see to what degree the current restriction is necessary and why it is there.

3 Likes

Hi @PeZsmistic
We’re going to update the docs to reflect that fact that if your DragStyle function returns nil, the object will not be moved. So if you don’t have enough information to perform your function, you can return nil and it won’t have an effect. It also gives you a way to stop moving your object mid-drag if you have reason to do so.

I also updated the Lift&Carry demo and models to set myMovingPart = clickedPart on mouseDown; and for the DragStyle function to return nil if myMovingPart is nil.
I’ve left the default in the script to set myMovingPart = script.Parent so that things always work on dragStart in this version.

But the script is now more portable and if myMovingPart can’t be known prior to dragStart, it will leave the part where it is on mouseDown and move it with the first mouseMotion.

It would be better if the signals always arrived in the correct order; but the straightforward fix to this did not work because the dragStart signal is sent as a signal whereas the dragStyle is called within the flow of the thread that sends the signal; so we’re not guaranteed to have the timing we want.

3 Likes

Hey @PrinceTybalt ,
On the tycoon how can i get all dropper parts being spawned to allow the tycoon carrying? Reason why i’m asking is that I want droppers to be spawn earlier and then they can upgrade the base to get conveyors and burners but want them to carry to the power station first off? Here is my droppers script:

local dropsFolder = game:GetService("ServerStorage").Drops
local Debris = game:GetService("Debris")
local Players = game:GetService("Players")

local Dropper = {}
Dropper.__index = Dropper

function Dropper.new(tycoon, instance, ownerPlayer)
	local self = setmetatable({}, Dropper)
	self.Tycoon = tycoon
	self.Instance = instance
	self.Rate = instance:GetAttribute("Rate")
	self.DropTemplate = dropsFolder[instance:GetAttribute("Drop")]
	self.DropSpawn = instance.Spout.Spawn
	self.OwnerPlayer = ownerPlayer  -- This assumes you're passing the player who owns the dropper
	self.DebrisTome = 1800

	return self
end

function Dropper:Init()
	coroutine.wrap(function()
		while true do
			self:Drop()
			wait(self.Rate)
		end
	end)()
end

function Dropper:Drop()
	local replicatedStorage = game:GetService("ReplicatedStorage")

	local drop = self.DropTemplate:Clone()
	drop.Position = self.DropSpawn.WorldPosition
	drop.Parent = workspace  -- Parent the drop to workspace or a specific folder within workspace

	if drop:IsA("BasePart") then
		drop:SetNetworkOwner(self.OwnerPlayer)  -- Set the network owner to the owner player
	end

	-- Add the LiftAndCarry_Physical_ClientScript to the drop
	local existingLocalScript = replicatedStorage:FindFirstChild("LiftAndCarry_Physical_ClientScript")
	if existingLocalScript then
		local clonedLocalScript = existingLocalScript:Clone()
		clonedLocalScript.Parent = drop
	end

	-- Add the DragDetector to the drop
	local existingDragDetector = replicatedStorage:FindFirstChild("DragDetector")
	if existingDragDetector then
		local clonedDragDetector = existingDragDetector:Clone()
		clonedDragDetector.Parent = drop
	end

	Debris:AddItem(drop, self.DebrisTime)
end

return Dropper

I’ve tried the same method for my trees but they dont seem to be draggable for some reason.

1 Like

Try to test it by launching roblox and joining your experience.
If it does work there, try disabling plugins, they may interrupt dragging, which i still don’t clearly understand why.
If it did not help, then you need to search for any errors or break points in script.

1 Like

@MonsterStepDa based on past discussions, I assume this is working for some objects already? So there is something different about your trees than that other types of objects? If you want to expand the description of the problem and what’s different about the trees more fully, or post a test world ,or send me one in a message I can take a look, but from what I know so far, I can’t help.

1 Like

@PrinceTybalt
A major bug seems to be apparent with the DragDetectors. I submitteda report to the bug team, but I figure it might even be faster to report it here to you directly as well.

Issue Description:

When a Drag Detector is Disabled while being used (Dragged) by a player. Any other player will be unable to use that drag detector, no matter what you do or try.

:arrows_counterclockwise: Reproduction:

Repo is rather simple.

  1. Add a functioning DragDetector to an object.
  2. Have one player drag it.
  3. Disable the DragDetector while the player is dragging it.
  4. Enable the DragDetector.
  5. Attempt to have any other player try to drag the object. It will not be possible.
1 Like

Hello @LadyAka thanks for reporting this. I have a similar test I run that doesn’t exhibit this problem.
This little script is working okay:

local dragDetector = script.Parent

do
	dragDetector.DragStart:Connect(function()
		-- start 2 second timer
		wait(2)
		print("Disabling DragDetector")
		dragDetector.Enabled = false
		wait(.1)
		print("Enabling DragDetector")
		dragDetector.Enabled = true
	end)
	dragDetector.DragEnd:Connect(function()
		print("Drag End")
	end)
end

So I need some more details to figure out what is broken for you.
[1] does your DragDetector have runLocally set to true or false (the default)? I assume it’s false since you are talking about multiple players dragging the same object.
[2] You said you are disabling the DragDetector while the player is dragging. How are you disabling the DragDetector? Through a script?
[3] When you enable the DragDetector, is this also through a script? Do you enable the DragDetector while the first player is still dragging, or sometime later?

If you can post a simple test world that shows the problem that would be even better.

1 Like

@PrinceTybalt I need help… again :frowning: Sorry for bugging you but how would I make this https://www.youtube.com/watch?v=jP3y9Wi0o_k

Into this? https://youtu.be/lVSyJOhDYIk

A few things first, here are my properties

And how would I make it not go so far away? What you replied did not make sense sorry. :frowning:
-xxoof_oofoofxx

2 Likes

@xxoof_oofoofxxALT for the behavior you want, you should use the style from the Lift & Carry Game. You can download a copy of that game. There are two variations, one moves geometric style and the other physical style. They require a special script, this behavior is not baked into the DragDetector alone.
You can also grab just the two models separately:
Lift-And-Carry-Geometric or Lift-And-Carry-Physical.
To use these you are going to need to need to put all the children of the part from that model below your own part.

3 Likes

Thank you! But I have a question; I was studying the scripts and found this:
Screenshot 2023-10-30 160304
Why is there an error, or is that supposed to be there?

2 Likes

@xxoof_oofoofxxALT Oh, hurray! Since I started working here, they deprecated Blacklist and Whitelist in favor of Exclude and Include.
I’ve fixed the scripts and uploaded the game/models again. Thanks.

1 Like