DragDetectors [Beta]

Oh okay, I misunderstood then, thanks for your help :sweat_smile:

2 Likes

Thanks so much for all of this info. Iā€™ve gone ahead and followed your advice - I ended up enabling the RunLocally property and putting the code into a local script, and also changed the ResponseStyle property from Physical to Geometric as this worked better when I unanchored the object.

I polished up the code a little and made it so it now takes the camera CFrame (more specifically, the direction the player is looking in) into account when returning the position using some math. Now, Iā€™m stuck on another slight issue that Iā€™m trying to overcome:

Essentially, the old and outdated system Iā€™m trying to mimic used the deprecated BodyPosition object to control the position of the item when itā€™s held. The thing is, Iā€™m pretty sure (correct me if Iā€™m wrong) a BodyPosition object will just cease to work if the Position property is set to a Vector3 inside of a part, because it essentially tweens the position of the part itā€™s managing to the target one, and itā€™ll just stop if it canā€™t reach it (when it hits an object?). At least, thatā€™s what I think is happening here. Video 1 is what I currently have and video 2 is what Iā€™m trying to achieve (uses BodyPosition, obviously). I want my system to have the same behavior as the old one, where it doesnā€™t allow the object youā€™re holding to go through others - simply because itā€™s unrealistic. Do you think thereā€™s any way I could achieve this without writing extremely complex code that uses raycasting? :smiley:


At least Iā€™m getting somewhere! :grin: Thanks again for your help.

1 Like

Weā€™re currently exploring the possibility of geometric-like drag with collisions, but itā€™s not anything concrete yet.

Would a physical response style (sorry for bringing you back to that) with an extremely high Responsiveness and ApplyAtCenterOfMass being enabled emulate that by any chance?

4 Likes

Fun and useful feature. Might become handy for something like obbys, where you have to drag your platform all the way to the end, while avoiding bombs getting on your platform.

1 Like

A geometric drag system with collisions would be absolutely awesome. Iā€™m sure thereā€™s lots of developers who have use cases similar to mine that would benefit from this, so if you could look further into it thatā€™d be amazing. :slightly_smiling_face:

I tried your solution and yes, it does emulate it to some extent - it allows me to achieve nearly the same effect as the old system. The thing is, itā€™s quite clunky and often glitches a little when it comes into contact with another part. It also isnā€™t very precise, whereas with the older system the object would almost mold into the object it collides with. Itā€™s sadly not as smooth as it could be, but itā€™s definitely somewhat close to what Iā€™m trying to achieve!

Do you think the idea of a drag system with collisions that you mentioned would be able to replicate this behavior in an even smoother and more precise manner?

4 Likes

This is a really interesting discussion.
It would be nice to be able to drag Anchored objects and have them honor collisions.
I did some investigation with the current state of things, and my best results were:

  • using local scripts
  • using a custom DragStyle that places the object in front of the head (not the root) of the active player, and also adds a tilt that is taken from the current camera; a variation on @bvetterdaysā€™s earlier version
  • modifying the placement by doing a raycast, and if the hit is closer than where Iā€™d normal float it in front of me, then putting it where the ray hits
  • using a non-anchored object that I move in Geometric Mode. This anchors the object while moving so it stays exactly with the cursor, but when you let go it drops

There are problems, I think, with network ownership; we may need to hold onto it for the entire time and weā€™re not, so sometimes I lose control of it; and Iā€™ve made no RemoteEvents to replicate the results to other players.

But i did get some motion that feels okay when it is running well:

Here is the place file with my example and scripts. Anyone feel free to use. Thereā€™s are two burgers. The red one is non-anchored, and drops; the blue one is anchored, and stays where you leave it
StayInFront_03.rbxl (93.8 KB)

For those who donā€™t want to open up the file, the Local Script looks like this:

local dragDetector = game.Workspace:WaitForChild("UnanchoredPart"):WaitForChild("DragDetector")

local DISTANCE_IN_FRONT = 3
local OBJECT_DEPTH = 0.5

local draggingPlayer = nil
local lastViewFrame = CFrame.new()

dragDetector.DragStart:Connect(function(player)
	draggingPlayer = player
end)

dragDetector.DragContinue:Connect(function(player, ray, viewFrame)
	lastViewFrame = viewFrame
end)

dragDetector.DragEnd:Connect(function(player)
	draggingPlayer = nil
end)

local function getDistanceForPlacementAndHitCFrame(rayToShoot, dragDetector, character)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {dragDetector.Parent, character }
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

	local hitPoint = Vector3.zero
	local hitNormal = Vector3.yAxis

	local raycastResult = workspace:Raycast(rayToShoot.Origin, rayToShoot.Direction, raycastParams)	
	if raycastResult then
		hitPoint = raycastResult.Position
		hitNormal = raycastResult.Normal.Unit

		local lookDir1 = hitNormal:Cross(Vector3.xAxis)
		local lookDir2 = hitNormal:Cross(Vector3.yAxis)
		local lookDir = if lookDir1.Magnitude > lookDir2.Magnitude then lookDir1.Unit else lookDir2.Unit
		local hitCFrame = CFrame.lookAt(hitPoint, hitPoint + lookDir, hitNormal)
		local distanceToHit = (raycastResult.Position - rayToShoot.Origin).Magnitude
		local distanceToTranslate = distanceToHit - 0.5 * OBJECT_DEPTH
		return distanceToTranslate, hitCFrame
	end	
	return rayToShoot.Direction.Magnitude, CFrame.new()
end

local function followTheCursor(cursorRay, dragDetector)
end

dragDetector:SetDragStyleFunction(function(cursorRay)
	if draggingPlayer == nil then
		return dragDetector.Parent.CFrame
	end
	local character = draggingPlayer.Character
	if character then
		local headPart = character:FindFirstChild("Head")
		if headPart then
			local headLocation = headPart.CFrame.Position
			local cameraTiltAngle = math.acos(lastViewFrame.UpVector:Dot(Vector3.yAxis))
			if lastViewFrame.LookVector.Y < 0 then
				cameraTiltAngle *= -1
			end
			local cameraTiltMatrix = CFrame.fromAxisAngle(headPart.CFrame.RightVector, cameraTiltAngle)
			local tiltedHeadLookVector = cameraTiltMatrix:VectorToWorldSpace(headPart.CFrame.LookVector).Unit
			local rayToShoot = Ray.new(headLocation, tiltedHeadLookVector * DISTANCE_IN_FRONT)
			local distanceForPlacement, hitCFrame = getDistanceForPlacementAndHitCFrame(rayToShoot, dragDetector, character)
			local newPosition = headLocation + tiltedHeadLookVector * distanceForPlacement
			return hitCFrame.Rotation + newPosition
		end
	end
	return dragDetector.Parent.CFrame
end)

7 Likes

very nice feature!! puzzles are gonna go hard with this one.

4 Likes

This looks cool! Iā€™ve tried it out and although itā€™s a little glitchy due to NetworkOwnership issues, itā€™s probably the best weā€™ll be able to get it for now. The raycasting works well when helping it almost ā€œattachā€ to parts it collides with, except if you put it too low, too high or in other weird positions, it no longer works. Iā€™ll try to iterate on this in the coming days to improve it even more and Iā€™ll let you know how I go if I can get it working any better than it is currently, however, this is a result I personally am very pleased with - I didnā€™t think it would be possible to get a result like this at all. Also, itā€™s interesting what youā€™ve done to determine the position. I should probably start using this math myself as it also works in third person. Thanks again for releasing this feature! :heart:

3 Likes

Hmm. Is there any way I could halt the drag on the client via a local script? If not, maybe you could consider implementing a method to do so, such as :StopDrag(). :thinking:

I have certain use cases for this such as when a player either purposely or accidentally gets an object stuck behind a bench (for example) and walks away from it. My script detects when the player is more than 9 studs away from the item they have equipped and if this is the case, it forces them to drop it, which also means the drag needs to be forcefully stopped. If thereā€™s a hacky method thatā€™d allow me to do this, please do let me know, but regardless, a built-in method for it would be awesome.

2 Likes

Yes, you can halt a drag in a script!

Set dragDetector.Enabled to false, during a dragContinue or other callback, and
the DragDetector will gracefully end any drag in progress.

You will need to set Enabled back to true if you wish to use it again.
It might work to just set it back true during your dragEnd callback?

3 Likes

Gotcha. It was indeed working, it just seemed as though it didnā€™t because the mouse cursor remained the same - wouldnā€™t it be better if it changed back to the normal cursor once the drag is stopped by a script (so, for example, the user can be made aware of it)? Alsooo, any chance the DragEnd event can be fired whenever this happens, or was this purposely not implemented? This was another reason why I couldnā€™t tell that disabling it didnā€™t work.

If thereā€™s a reason this hasnā€™t been added, no worries at all. Please do enlighten me as I donā€™t know much about how these systems are usually structured and implemented :slightly_smiling_face: If not, itā€™s another suggestion I have that would make it much easier for us developers.

Although the thing is I assume itā€™s more of an issue with ClickDetectors (as this is what is used backend, correct?) than with DragDetectors themselves so no problem if youā€™re unable to make any changes in this area.

Once again, canā€™t thank you enough for all of your help. :smile:

3 Likes

Well, it depends whether the mouse is still over the object. If itā€™s not then the cursor should return and it may be a bug. We will look into it. Thanks for reporting these unexpected behaviors. Itā€™s the best thing you can do for us as a beta user.

Note that soon we will have a cursor that changes to a closed hand when dragging. On DragEnd, this should change into an open hand if the cursor remains over the object, or to the default cursor if not.

4 Likes

Thatā€™s awesome, thanks so much - I couldnā€™t be more appreciative of your help. And this will all be done before it rolls out publicly? :smile:

This would be perfect - I know some developers that have custom-coded systems that do exactly this, so integrating it directly would save myself and others who want systems similar to these so much time.

Once these fixes are rolled out & also once the whole system is fully enabled I hope some sort of notification is sent out here, as I canā€™t wait to test this with others :grinning:

P.S. Mentioned this earlier but you mightā€™ve skimmed over it; is there any reason the DragEnd event isnā€™t fired when the dragā€¦ well, ends after the detector is disabled? Itā€™d be awesome if it did! :pray:

2 Likes

Yes, the new open/closed cursors will be in place before the full public release of DragDetectors.

As for DragEvent not being fired when we set the DragDetector disabledā€¦ this should work too, and is probably caused for the same reason the cursor does not return to normal. Weā€™ll be looking into both.

6 Likes

After internal discussion, we have decided to make a change thatā€™s somewhat related.

Currently, if you drag a model (with a dragDetector parented by a model), geometric mode only anchors the part that was clicked-- the other parts associated with the model are not affected.

This will be changed in the upcoming weeks to anchor all of the parts under a model, and restore them to their original states after it ends.

We, however, do not plan to change the behavior when you drag a part under a model via a dragDetector parented by that part.

6 Likes

Any word on when this will be out of beta? This would be a really useful feature for one of my games!

2 Likes

We canā€™t give you a date. We are making some tweaks and fixes based on all of your great feedback. We donā€™t want to go live until those changes are finished and functional.
@DeFactoCepti , @Urukeli and I will post updates here as changes become available.

Until then, please post here if things seem broken or confusing. :slight_smile:

9 Likes

Great feature, that will make projects that ive wanted to do much easier.

But is there any plans to make the default cursor image for drag detectors and click detectors match with the new roblox cursor?

2 Likes

New default cursor images for DragDetector are coming. It will look different when dragging (closed hand) than when hovering (open hand); and you will be able to customize both.
I am not certain whether the default ClickDetector cursor will change as well.

6 Likes

Hey folks, @here!
I wanted to let everyone know that we enabled DragDetectors for Team Test, so you can try out your experiences with other developers. Canā€™t wait to see what mechanics you would come up with.
Make sure your Drag Detectors beta is on for all participants, so the feature would work properly. To start Team Test make sure to invite some friends using blue Collaborate button in title bar to edit experience with you, then press ā€œTeam Testā€ button in main menu. Others would be able to Join the test once you started testing. Server would reload saved experience with the last Team Test participant leaving.

14 Likes