Announcing DragDetectors!

@MonsterStepDa
oooh the clawwww.
TheClaw
I worked at Pixar for a while but not during the Claw era.

So for this, DragDetectors are only really applicable to the controls. The claw mechanism and how they respond to your controls is a totally separate problem.

For the controls, you’re probably going to want to have some 1D joysticks, and maybe a button? The button would be to tell the claw to drop, and the joysticks would move the claw forward/backward and left/right.

For the button, check out the 3 new button styles in DragDetectors TestWorld 2. You’ll probaby want to riff off of the left one.

For the joystick, you can go one of two ways. [1] You can make a knob on a 1D slider, like the one ParticleLineSlider in that same world. It will translate and not rotate like a joystick, but probably is a little easier to implement. You can always just use a beam to connect the center of the know with the base of the joystick on the console and it will kind of look like it’s rotating . Note that you’ll want to set the referenceInstance to be another object like the backplate, and then use MinDragTranslation/MaxDragTranslation to limit the motion. Then you can read the DragTranslation value to decide how to move the claw. [2] you can make a rotating joystick. This involves using a DragStyle of RotateAxis and limiting the motion with minAngle and maxAngle. I don’t have an example of this yet.

3 Likes

@Almonty7655 ooh you creators make such pretty models. Most of my tests are just chunky blocks to illustrate a concept.

The reason your rotation looks like it is resetting each time is because your referenceInstance is the handle itself, which is the object you are moving. In the model I attached, I renamed your parts for easy reference. I’ve set the DragDetector’s referenceInstance to be the InnerShaft, which remains fixed when you drag, so now you can see the angles do not reset to 0 each time you drag.

I also rotated the 2 attachments to point their X axis in the same direction as the handle’s X axis. Things always behave better if you align them nicely.

Then I set the HingeConstraint LowerAngle to -90 and UpperAngle to 90.

Then, in studio edit mode, I turned off all 4 of the Dragger tools: select/rotate/translate/scale. You can do this by clicking the select tool twice. When you do this, events fall to the DragDetectors and you can adjust them in edit mode.

The constraint feedback in edit mode shows you a green arc with the limits; and it showed a red arc indicating that the position was outside the limits. To get it to that it doesn’t move when the game starts, I rotated the handle with the DragDetector until the red disappeared, the axes aligned, and the green arc looked like a smile, nicely centered about the downward pointing axis representing 0 rotation.

Now when I hit play it looks nice. The fixed model is attached. Note that since your HingeConstraint has nice limits, you don’t even need to bother with the DragDetector’s minAngle and maxAngle.

@Almonty7655 this is such a nice example. Do you mind if I added it to one of the DragDetector test worlds so that others may benefit? I will put your name on the little sign to credit you.
DragdetectorValveRepro_Fixed.rbxl (92.3 KB)

2 Likes

Another tip about rotations in general that’s especially important when you use minAngle and maxAngle.

Because of the way euler rotations work, you are going to get much nicer looking values if your rotation axis is the YAxis(0,1,0) or ZAxis (0,0,1) than if it is the XAxis(1,0,0).

Check out this world here:
RotateAxis_YZ_BetterThan_X.rbxl (54.5 KB)
It has 3 boxes. The Red rotates about a pivot using Axis = XAxis.
watch the DragFrame.Orientation value when you rotate it and you’ll see that the Y and Z values change in funny ways. Sometimes they are 0, other times 180. This is because when you extract euler rotations from a matrix, the order of which is YXZ, when the middle value is X there are more than one ‘answer’ sometimes.

On the other hand, try the Green or Blue boxes which rotate about Y and Z, and watch the DragFrame.Orientation of THOSE values when you rotate. They are nice and clean, just one changing value and the others remain at 0. This is going to be much easier to work with, and easier to understand when you want o use minAngle and maxAngle.

2 Likes

Thanks, @PeZsmistic !
I updated the place and also the two models to use your fallback to rootPart when the character does not have a head.
I also added mention of your help in the opening credits of each model. :slight_smile:

3 Likes

Thank you for the explaination, DragDetectors are a lot more complicated than I originally thought, and yeah, go for it as a demo.

2 Likes

I wish staff were this involved with some of the other feature as you guys are as with this, keep up the great work! I may not have a use for the 3D aspect for dragging but I can definitely use it 2D stuff

5 Likes

Thanks, @SillyMeTimbers.
It’s great to be appreciated. For our part, this is a rare opportunity to get instant feedback from all over the world. We learn a lot hearing about your frustrations, suggestions, and successes.

In that spirit:
How would you use DragDetectors in 2D situations? @DeFactoCepti is starting to look into this and the more we know about your use cases, the better.
So far the 3 main areas we’ve heard about are:

  • allowing users to customize where 2D elements are on the screen; location and size
  • movable 2D UI like sliders & knobs
  • 2D games like slider puzzles

I invite anybody reading this to chime in if you have other applications for DragDetectors in ScreenGui or SurfaceGui situations.

2 Likes

are you gonna add the ability to drag and drop using the drag detectors?

2 Likes

@IceCreamPickels from one window to another? No.

Or do you mean something different within a single game window?

2 Likes

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