Trying to make drag detector move to the edge of the limit if it can't follow the mouse

  1. What do you want to achieve? Keep it simple and clear!
    I want to replicate the tower placement shown in this video below using a DragDetector:

  2. What is the issue? Include screenshots / videos if possible!
    My current custom drag ResponseStyle only supports dragging the cursor (white part inside the square) while it is inside the placement limit.


    My goal is to have the cursor move to the edge of the drag limit if the mouse is outside the drag limit, to an equivalent position, as seen in the first video

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Could not find anything similar to this on the Dev Forum
    This is a code snippet for the placement system and custom drag response

local tile = level.Tiles[tilePos].parts.Node.Position
guide = placement_square:Clone()
guide:PivotTo(CFrame.new(Vector3.new(tile.X, tile.Y+2, tile.Z)) * CFrame.Angles(0, math.rad(45), 0))
guide.Parent = workspace
local guidePos = guide:GetBoundingBox().p
local mouse = player:GetMouse()
local cursor = guide.Part
local bound = guide.Frame.Box
local dragger = guide.Part.DragDetector
dragger.DragContinue:Connect(function()
	print("dragged")
	local pos = UserInputService:GetMouseLocation()
	local mouseray = camera:ScreenPointToRay(mouse.X, mouse.Y)
	local worldPos = workspace:Raycast(mouseray.Origin, mouseray.Direction*90)
	local part = Instance.new('Part')
	part.Size = Vector3.new(0.1,20,0.1)
	part.Anchored = true
	part.Transparency =1 
	part.Parent = workspace
	part.Position = Vector3.new(worldPos.Position.X, guidePos.Y, worldPos.Position.Z)
	local inSquare = false
	local touchingParts = part:GetTouchingParts()
	part:Destroy()
	for _, instance in touchingParts do
		if instance.Name == 'Box' then
			inSquare = true
			break
		end
	end
	if inSquare then
		cursor.Position = Vector3.new(worldPos.Position.X, guidePos.Y, worldPos.Position.Z)
	end
end)
2 Likes

If the mouseRay world position was outside of the drag limit, then you create another raycast towards the drag limit part and set the filtertype to only collide with the drag limit. Just move the dragdetector part to the raycast position.

if inSquare then
	cursor:MoveTo(Vector3.new(pos.Position.X, 2, pos.Position.Z))
else
	local look = CFrame.new(Vector3.new(pos.Position.X, boxPos.Y, pos.Position.Z), boxPos)
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Include
	params.FilterDescendantsInstances = {box}
	local raycast = workspace:Raycast(look.Position, look.LookVector, params)
	if raycast then
		cursor:MoveTo(Vector3.new(raycast.Position.X, 2, raycast.Position.Z))
	end
end

However I encountered another bug regarding the cursor itself, which I have posted about here

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.