I wrote some code that mimics drag detectors and wanted to make it snap to a defined position when dragged close enough. For that behavior, I wrote the following code, tested it, and it works:
-- Drag detector behavior transcluded here
dragPart:PivotTo(targetPosition)
if (snapPosition.Position - dragPart.Position).Magnitude <= 1 then
dragPart.Parent:PivotTo(snapPosition)
end
However, this code is all inside a while loop. In my head, it’s moving dragPart’s parent between two positions really quickly. While I can’t visually see it happening, I’m concerned that this is a works-on-my-machine kind of problem and that any interruption to the program (eg. lag) will ruin the illusion that nothing is happening. And I don’t want to just make the code pivot dragPart to snapPosition because it’s slightly offset from its parent, which is what I really want pivoting to snapPosition. Is this a valid concern? Is there a better way to achieve the same effect?
you can maybe lerp between the positions to show it snapping.
dragPart:PivotTo(targetPosition)
if (snapPosition.Position - dragPart.Position).Magnitude <= 1 then
local lerpTable = {}
for c=0,1,0.1 do
lerpTable[#lerpTable+1]=dragPart.Parent:GetPrimaryPartCFrame():Lerp(snapPosition,c)
end
for _,cframe in pairs(lerpTable) do
dragPart.Parent:PivotTo(cframe)
wait()
end
end
However I would also recommend some kind of snap that shows when it snaps to something that way the user can tell
From what I can tell, the code you provided eases dragPart.Parent into snapPosition. However, it’s already snapping the way I want it to: the second it gets too close to snapPosition. My concern is whether or not making the program move dragPart.Parent to targetPosition only to move it back to snapPosition immediately afterward is a bad idea. Specifically, I’m concerned that this operation will become visible if it takes more than its normal ~50 milliseconds to execute (eg. due to lag or a worse machine’s capabilities), which I don’t want happening.
Of course, this is all on the assumption that the code you suggested does what I think it does. If it does something different, could you explain how it would help eliminate my concern? It looks like it’s still moving dragPart to targetPosition before immediately moving it back to snapPosition, which is the main source of my concern.
if (snapPosition.Position - targetPosition.Position).Magnitude <= 1 then
dragPart.Parent:PivotTo(snapPosition)
else
dragPart:PivotTo(targetPosition)
end
that way itll only move 1 of them and not move it back.
This code might’ve worked if I wasn’t an idiot and wrote the correct condition in this post. The condition is actually (snapPosition.Position - dragPart.Parent.Position).Magnitude <= 1 (note that it uses dragPart.Parent.Position and not dragPart.Position).
As for why I don’t want to use targetPosition.Position to find the distance from snapPosition, targetPosition is actually centered on dragPart, which is offset from the center of dragPart.Parent.
Basically, what’s supposed to happen is dragPart:PivotTo(targetPosition) moves dragPart.Parent through weld constraints. Then the code checks if dragPart.Parent is close enough to snapPosition and moves it back if it is. I don’t want to just use dragPart to find the targetPosition either because it’s offset from dragPart.Parent’s origin, which is what I really want targetPosition to be. I also don’t want to set dragPart’s origin to my desired targetPosition because it is being used for something else. And I don’t want to use math to adjust it, because there are 5 other hitboxes that would need their own calculations. Not that I want to do that anyway, because I’m planning to make a similar script where the calculation for the offset would end up changing with every interaction. Besides, if I change the model later on, that math would be a pain to change as well.
I did end up trying some variation of your code before making this post. It ended up snapping dragPart.Parent to snapPosition, but by the time it loops back, the condition is true again and dragPart.Parent is snapped to snapPosition. As a result, I was never able to move it.
Now that I’m writing this all out, the situation is really convoluted, isn’t it? Sorry for being really unclear at the beginning.
In the week of no responses, I found a replacement for the (snapPosition.Position - dragPart.Position).Magnitude <= 1 condition. It just required a load more math and a bit of manipulating on the model. I’ve replaced it with snapPosition.Position - (targetPosition - (dragPart.Position - dragPart.Parent.WorldPivot.Position))).Magnitude <= 1. (targetPosition - dragPart.Position - dragPart.Parent.WorldPivot.Position)) gets me the position of dragPart.Parent’s position to which I can use to directly compare to the snap position.
And now I know why math is still useful for high-level-abstraction programmers.