Announcing DragDetectors!

Is it possible to say, have secondary axis controlled without a button modifier?

For example, I have a CylindricalConstraint. I want Y to change how far along it slides and X to control the rotation.

Also, really happy with this high quality update!

1 Like

@Ylsid yes, you can do that.

This little world has a script that switches between TranslatePlaneOrLine and RotateAxis when you press the Y key, and puts it back when you let go.

The general method is to register an action through the ContextActionService to watch for key press and release; and then make changes to the DragDetector configuration; and then call RestartDrag.
I return Enum.ContextActionResult.Pass so that others can listen to the key event.

In the place where I configure the DragDetector, you could change the DragStyle, Axis, and SecondaryAxis, or pretty much any property however you like. Just make sure those changes occur before you call RestartDrag.
And of course you could use different keys, but this gives the general method.
ChangeBetweenRotateAndTranslate.rbxl (55.2 KB)

1 Like

That wasnā€™t quite what I was asking, but I solved the problem by turning DragDetectorResponseStyle to Custom and listening to the coordinates returned by DragFrame. I used the X axis to change the angular on the cylindrical constraint, and Y axis to control the servo TargetPosition. When I said Y and X I meant axes, sorry!

Thanks for your help anyway

3 Likes

@Ylsid nicely done!
That is exactly the sort of thing that the Custom ResponseStyle was built for!

2 Likes

Hello @MrVietChopsticks ,

I have created a variation of the Lift And Carry: Physical model that you can pick up by the point you click on, and carry around so it dangles from that point.
The new model is available at this link: Dangle And Carry and has been added into the Lift And Carry Game.

The script now has a variable at the top, DO_DANGLE which switches between the old and new behavior.
To dangle, I needed to change 3 things:
[1] set applyAtCenterOfMass to false so that forces are applied at the point where you click
[2] set maxTorque to 0 so that the DragDetector does not try to align the orientation
[3] Change the script to save the hitPointInobjectSpace on dragStart; and then to adjust the frame returned from the dragStyle function (which is applied to the pivot in worldspace) to subtract the worldSpace offset of the original hitPoint.

I understand that youā€™ve got an API request, but in the interimā€¦ does this give you what you need?

3 Likes

Hi @PrinceTybalt my cristmass obby is today published all levels with dragdettectors you can play each day a new level until Christmas and with cristmass come there a cool level with dragdettectors too

For my game I made with the game jam in the summer the beta release is soon and my scripter @0Shank have made his own draging system to build and on ui

4 Likes

It suddenly doesnā€™t work anymoreā€¦
Is this a my problem? I try opening in studio but it still doesnā€™t response
I wonder if itā€™s on my side and my computer is too old or Robloxā€™s having a problem
Please let me know :melting_face:


1 Like

Is there a way for drag detectors to be detectable through walls? Id rather not have to make CanCollide and CanQuery off to achieve this.
My use case involves moving an object around, but once it goes through another part, it ceases to be detectable. Any way around this? Video below:

EDIT: I found a solution in the other DragDetector thread where it discusses collision groups.

3 Likes

@MrVietChopsticks oh no! I broke something with my last update. Thanks so much for reporting this.

Iā€™ve fixed it, all should be working again. Please let me know if you still have trouble.

2 Likes

Hi Folks,

Hereā€™s a little script that makes it so players look at, and reach for, any item that they drag with a DragDetector. This makes it so you can see who is moving what.

Itā€™s just a first experiment, but since I shared it with another creator, I wanted to give everyone an equal chance to use it.

The script finds all DragDetectors on startup, and adds a dragStart callback that [a] adds IKControls for the player if they are not already there, and [b] sets the clickedPart of the DragDetector as the target of IKControls on the head (lookAt) and right hand (position). It also adds an dragEnd callback that nils out the targets.

Thereā€™s lots to be improved: better transitions, tracking the clicked location instead of the part, and choosing the closer hand. But itā€™s neat, and short, and I thought you might find it useful.

Hereā€™s a little video:

Hereā€™s a copy of DragDetectors_TestWorld1 that uses the script:
DragDetectors_TestWorld_1_withIKReach.rbxl (141.5 KB)

And hereā€™s what the script looks like:

-- find all DragDetectors in the workspace
local function findAllDragDetectorsInWorkspace()
	-- find all DragDetector instances in the workspace
	local oldDescendants = game.Workspace:GetDescendants()
	local newDescendants = {}
	while #newDescendants ~= #oldDescendants do 
		wait(1)
		oldDescendants = newDescendants
		newDescendants = game.Workspace:GetDescendants()
		warn(#newDescendants)
	end
	warn(#newDescendants)
	return newDescendants	
end


local intializedPlayers = {}
local function setupPlayerIK(player)
	if not player then
		return
	end
	if table.find(intializedPlayers, player) then
		return
	end
	
	warn(player.Name)
	local rightHand = player.Character:WaitForChild("RightHand")
	warn(rightHand.Name)
	local rightHandIKControl = Instance.new("IKControl")
	rightHandIKControl.Parent = player.Character:WaitForChild("Humanoid")
	rightHandIKControl.Name = "rightHandIKControl"
	rightHandIKControl.Type = Enum.IKControlType.Position
	rightHandIKControl.EndEffector = rightHand
	rightHandIKControl.ChainRoot = player.Character:WaitForChild("RightUpperArm")

	local head = player.Character:WaitForChild("Head")
	warn(head.Name)
	local headIKControl = Instance.new("IKControl")
	headIKControl.Parent = player.Character:WaitForChild("Humanoid")
	headIKControl.Name = "headIKControl"
	headIKControl.Type = Enum.IKControlType.LookAt
	headIKControl.EndEffector = head
	headIKControl.ChainRoot = player.Character:WaitForChild("UpperTorso")
	
	table.insert(intializedPlayers, player)
end

local allDescendants = findAllDragDetectorsInWorkspace()

for _, descendant in allDescendants do
	if descendant:IsA("DragDetector") then
		descendant.DragStart:Connect(function(player, ray, viewFrame, hitFrame, clickedPart)
			setupPlayerIK(player)
			player.Character.Humanoid.rightHandIKControl.Target = clickedPart
			player.Character.Humanoid.headIKControl.Target = clickedPart
		end)		
		descendant.DragEnd:Connect(function(player)
			player.Character.Humanoid.rightHandIKControl.Target = nil
			player.Character.Humanoid.headIKControl.Target = nil
		end)
	end
end
3 Likes

This reminds me of the place I made as a demo when Drag Detectors were still in beta:

https://ro.blox.com/Ebh5?pid=share&is_retargeting=true&af_dp=roblox%3A%2F%2Fnavigation%2Fgame_details%3FgameId%3D4997677778&af_web_dp=https%3A%2F%2Fwww.roblox.com%2Fgames%2F14472953901

I was somewhat trying to match the VR laser pointer, but I think yours is better because it tracks the head and the hand

3 Likes

The other month I did something similar with ProximityPrompts (the code below). It made me think about how itā€™d be nice to have something like ProximityPromptService, but for DragDetectors. Because without something like that, itā€™s really hacky writing code that applies to all DragDetectors (ex. findAllDragDetectorsInWorkspace from your script).

local Players = game:GetService("Players")
local ProximityPromptService = game:GetService("ProximityPromptService")

ProximityPromptService.PromptTriggered:Connect(function(promptInstance: ProximityPrompt, playerWhoTriggered: Player)
	if promptInstance:GetAttribute("HideEngagement") then
		return
	end

	local character = playerWhoTriggered.Character
	if character==nil then
		return
	end

	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid==nil or humanoid:GetState()==Enum.HumanoidStateType.Dead then
		return
	end

	local oldEnagagementIKControl = humanoid:FindFirstChild("EngagementIKControl") :: IKControl
	if oldEnagagementIKControl then
		oldEnagagementIKControl:Destroy()
	end

	local enagagementIKControl = Instance.new("IKControl")
	enagagementIKControl.Name = "EngagementIKControl"
	enagagementIKControl.Type = Enum.IKControlType.Position
	enagagementIKControl.Weight = 1
	enagagementIKControl.SmoothTime = 0
	enagagementIKControl.Enabled = true
	enagagementIKControl.Parent = humanoid

	local promptParent = promptInstance.Parent
	local enagementTarget = if promptParent and promptParent:IsA("Model") then promptParent.PrimaryPart else promptParent

	enagagementIKControl.ChainRoot = character:FindFirstChild("RightUpperArm")
	enagagementIKControl.EndEffector = character:FindFirstChild("RightHand")
	enagagementIKControl.Target = enagementTarget
	
	local cleanupThread = task.delay(0.2, enagagementIKControl.Destroy, enagagementIKControl)
	
	enagagementIKControl.Destroying:Once(function()
		if coroutine.status(cleanupThread) == "suspended" then
			task.cancel(cleanupThread)
		end
	end)
end)
4 Likes

@0Tenth Yours is fantastic! And you did it first!

I am planning to add beams like yours as well to complete the connection.
But like I said, I wanted to share what I have, since Iā€™ve given it to other devs.

When I upgrade it (likely at the end of the year) I will post again and probably also upload a game.

2 Likes

Yes, it felt a little hacky, but itā€™s the best way available that I know of. A better way might be to use CollectionService, but that only tracks tagged instances, not instances by type. And I didnā€™t want to have to tag all the DragDetectors just to use the script. To make it more complete in a dynamic game, youā€™d probably want to add/remove DragDetectors from the list by reponding to game.Workspace.descendantAdded and descendantRemoved signals.

2 Likes

is there a way to disable the cursor icon change? i want it to stay the same before it hovers over the part

2 Likes

Running into a bug, where changing the anchored property of the part a dragdetector is attached to causes the part to glitch out. Restarting the drag using :RestartDrag does nothing, although the issue fixes itself once you let go of the dragdetector.


Note: using the default response style as the detector is made with instance.new, and changing the parts anchored property in a DragStart connection

3 Likes

We have a problem I think

I have now published my cristmass Obby but i tested it with players and Devs who never heard about dragdettectors and they not know how it works from player side

So I added prompt for information about how the level work

2 Likes

@zimroy the DragDetector has a ā€˜CursorIconā€™ and an ā€˜ActivatedCursorIconā€™ property,
If you set DragDetector.CursorIcon to rbxasset://textures/Cursors/KeyboardMouse/ArrowFarCursor.png
then you will have the same cursor as the default arrow until you press down!
Iā€™m not sure how this will work on all platforms since itā€™s loooking in the KeyboardMouse folder. So you might want to download that and upload it to a custom texture asset and use that assetId.

2 Likes

right, but what if someone is using a different/custom mouse texture?

1 Like

Well then you could write a script that gets the mouse icon (not sure but I think you can use UserIInputService.MouseIcon.Mouse.Icon) and set the DragDetector to use that icon.

If that icon is chaning dynamically your task is harder, but thatā€™s the approcah I would take. There is not a way to disable the DragDetector from setting the icon

3 Likes