Word Search Dragger / Vector2 math problem

I’m creating a word search game and I’m working on the mechanic for finding words. The logic for this works but I am having trouble with the dragger or “stretcher” part of the “handle” for this. In other words, I can find the word successfully and everything works as expected (so don’t worry about that), except the visualization of the stretcher/handle is…wrong. Here is my hierarchy. Handle is just an invisible handle frame, and Stretcher is the frame you are dragging that is being stretched.

image

Once you observe the difference in behavior in the two videos below, the problem should become clear. You can imagine how this would be a problem when you’re trying to circle a word but the pink stretcher doesn’t reach it.

  1. What do you want to achieve?
    This is the effect I’m trying to achieve. I shouldn’t post an offsite link, but this comes from a certain website that is probably the first result when you google “word search”.

  1. What is the issue?
    Here’s what mine looks like. You can especially see the problem when you turn the mouse to the left.

  2. What solutions have you tried so far?

Here’s my code, called on UserInputService.InputChanged. endPos is the mouse’s position Vector2.new(input.Position.X, input.Position.Y)

local distanceFromMouse = endPos - handle.AbsolutePosition
local angle = math.atan2(distanceFromMouse.Y, distanceFromMouse.X)
handle.Rotation = math.deg(angle)
	
local sizeX = distanceFromMouse.Magnitude / handle.AbsoluteSize.X --// didn't have to math.abs this after all
local size = UDim2.fromScale(sizeX, 1)
	
handle.Stretcher.Size = size

I’ve tried messing with Vector2 Cross and Dot; the concepts of them make sense to me when I see a visualization of it, but I’m not really sure how to apply them to my code yet. Not sure if they’re even relevant to a possible solution here.

@Exeplex’s solution in this post (third video) resonates with me because I suspect I could
rotate a pseudo “anchor point” (absolute position of where the stretcher needs to reach) and pass that as endPos based on the mouse’s rotation degrees around Handle’s AbsolutePosition (similar to how I rotate the handle above), rather than Vector2.new(input.Position.X, input.Position.Y). That might not make much sense though

Not sure where to go from here!

Please don’t hesitate to call me out if anything on this post doesn’t make sense or needs to be explained further, or if you need more information! I appreciate any and all help I can get. :heart:

I’m assuming the handle.AbsolutePosition property uses the top-left/right corner of the UI element. Try calculating the center of the UI element you’re dragging from instead of the AbsolutePosition. You’d want the center for both elements because the stretcher starts and stops at the center of the source letter and the mouse’s position respectively.

local center = handle.AbsolutePosition + Vector2.new(handle.Size.X.Offset / 2, handle.Size.Y.Offset / 2)

1 Like

As EncodedLUA mentions the pivot (place the frame rotates around) is in the top-left corner, but you want to center the rotation above the “box” and use that as a base for calculating both rotation and length.

My example:

My GUI:
The DragLine got AnchorPoint 0.5, 0.5 and Position Scale 0.5, 0.5 inside the pivot.

image

The code in SelectScript:

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

local mouse = Players.LocalPlayer:GetMouse()

local dragRotationPivot 	= script.Parent.DragRotationPivot
local dragLine 				= script.Parent.DragRotationPivot.DragLine

while RunService.RenderStepped:Wait() do
	-- Calculate a pivot that is on the middle of the start of the line by adding half the height
	local pivotPosition = Vector2.new(
		dragRotationPivot.AbsolutePosition.X + (dragRotationPivot.AbsoluteSize.Y / 2),
		dragRotationPivot.AbsolutePosition.Y + (dragRotationPivot.AbsoluteSize.Y / 2)
	)
	
	-- Create a vector with the diff between the start position and
	-- the current mouse position
	local positionDiffVector = Vector2.new(
		mouse.X - pivotPosition.X,
		mouse.Y - pivotPosition.Y
	)
	
	-- Use the length of that vector to set the length of the line
	dragLine.Size = UDim2.new(
		0, 
		positionDiffVector.Magnitude, 
		dragLine.Size.Y.Scale, 
		dragLine.Size.Y.Offset
	)
	
	-- Set the rotation based on the vector
	local angle = math.atan2(positionDiffVector.Y, positionDiffVector.X)
	dragRotationPivot.Rotation = math.deg(angle)
end