Finding whether a given Vector3 is within a plot

Hello!

I’m currently creating a placement system for fun and have found an issue when placing items. If stacking items, you’re able to exceed the plot boundaries. I was thinking I could use Rect but I am thinking that it wouldn’t maintain the rotation of the plot which would create issues once again.

I was thinking I could do it lazily by creating an extremely tall box and use :GetTouchingParts but this probably wouldn’t do me any good.

I was also thinking I could use Region3 but I haven’t had much luck with R3 in the past, it ends up being finicky and inaccurate.

local function snapToIncrement(vector, size, plotSize)
	local x = math.floor((vector.X / snap) + 0.5) * snap
	if x > plotSize / 2 then -- Ensures the part touching the plot doesn't exceed the bounds. The problem is that I'm not sure how to make it work when it's not a part touching the plot itself
		x = plotSize / 2
	elseif x < -plotSize / 2 then
		x = -plotSize / 2
	end
	local z = math.floor((vector.Z / snap) + 0.5) * snap
	if z > plotSize / 2 then
		z = plotSize / 2
	elseif z < -plotSize / 2 then
		z = -plotSize / 2
	end
	local newVector = Vector3.new(
		x,
		vector.Y + size.Y / 2,
		z
	)
	return newVector
end

mouse.Move:Connect(function()
	oldOrientation = part.Orientation
	local hit = mouse.Hit
	local target = mouse.Target
	if hit and target then
		local allowedFaces = target:FindFirstChild('AllowedFaces')
		local targetSurface = mouse.TargetSurface
		if allowedFaces then
			if targetSurface.Name == allowedFaces.Value then
				placementModule:ColourObjectPlaceable(part)
				if target ~= plot and not target:IsDescendantOf(plot) then
					target = plot
				end
				part.CFrame = hit
				local relativeCFrame = target.CFrame:ToObjectSpace(hit)
				local snappedPosition = snapToIncrement(relativeCFrame.p, part.Size, 50)
				local newCFrame = CFrame.new(snappedPosition)
				part.CFrame = target.CFrame:ToWorldSpace(newCFrame)
				part.Orientation = oldOrientation
				oldOrientation = part.Orientation
			else
				placementModule:ColourObjectFailingToPlace(part)
			end
		else
			placementModule:ColourObjectFailingToPlace(part)
		end	
	else
		placementModule:ColourObjectFailingToPlace(part)
	end
end)

Video:

2 Likes

You can use Object and World Space to your advantage in this case. The idea is that you can check if the part is within the plot, from a relative perspective.

local function positionIsWithinPlot(position)
    local relativePosition = plotCFrame:PointToObjectSpace(position)
    return (math.abs(relativePosition.x) < plotSize / 2
        and math.abs(relativePosition.y) < plotSize / 2)
end

I have not tested my code, but I hope that you get the idea. Here is an illustration:

1 Like

Thanks! I had taken a read at that article awhile ago and was thinking it could work in this case but wasn’t really sure how I’d go about it haha.

1 Like