How do I make my building piece follow through to the CFrameValue's CFrame after moving my mouse away 3 studs?

Hey, so I’m creating this fence building thing where you can create fences around a foundation and it works!

But the main problem is that when my mouse is moving to a new atttachment but then I make it go out of the 3 stud range, the fence just kind of stays in place where it was moving too and it looks really weird, whats an approach to fix this?

This is the code where I handle the logic

local attachment = Instance.new("Attachment")
attachment.Visible = true
attachment.Parent = workspace.Foundation

local cframeoffset = CFrame.new()

game:GetService("RunService").Heartbeat:Connect(function(dt)
	local unitray = camera:ScreenPointToRay(mouse.X, mouse.Y)
	local raycast = workspace:Raycast(unitray.Origin, unitray.Direction * 100, params)

	if raycast then
		for _, CFrameValue in ipairs(grid:GetDescendants()) do
			if CFrameValue:IsA("CFrameValue") then
				local distance = (raycast.Position - CFrameValue.Value.Position).Magnitude
				if distance <= 3 then
					local closestCFrameValue : CFrameValue = CFrameValue
					local finalCFrame
					attachment.WorldCFrame = closestCFrameValue.Value
					if closestCFrameValue.Parent.Parent.Name == "Back" or closestCFrameValue.Parent.Parent.Name == "Right" then
						finalCFrame = attachment.WorldCFrame + Vector3.new(0, fenceExtents.Y / 2 + 0.5, 0) + attachment.WorldCFrame.LookVector * fenceExtents.Z / 2
					else
						finalCFrame = attachment.WorldCFrame + Vector3.new(0, fenceExtents.Y / 2 + 0.5, 0) + attachment.WorldCFrame.LookVector * -fenceExtents.Z / 2
					end
					
					cframeoffset = cframeoffset:Lerp(finalCFrame, dt * 15)
					fence:PivotTo(cframeoffset)
				end
			end
		end
	end
end)

Well, you stop updating the cframe if the distance is too far.

Well not intentionally I only check if the mouse distance and the foundation attachment is less than 3 studs and then I allow everything to happen, but like I’m wanting it to like maybe follow through or go back to the last attachment?

If you just remove the if statement. Then it would just go through

Yeah but I have to check which attachment is the closest so I can attach it to the closest one

it appears that the issue lies with the for loop iterating through the CFrameValue objects. Currently, the code only updates the fence’s position when a CFrameValue within the range is found. Below script may not work.


local attachment = Instance.new("Attachment")
attachment.Visible = true
attachment.Parent = workspace.Foundation

local cframeoffset = CFrame.new()

game:GetService("RunService").Heartbeat:Connect(function(dt)
    local unitray = camera:ScreenPointToRay(mouse.X, mouse.Y)
    local raycast = workspace:Raycast(unitray.Origin, unitray.Direction * 100, params)

    local closestDistance = math.huge
    local closestCFrameValue = nil

    if raycast then
        for _, CFrameValue in ipairs(grid:GetDescendants()) do
            if CFrameValue:IsA("CFrameValue") then
                local distance = (raycast.Position - CFrameValue.Value.Position).Magnitude
                if distance <= 3 and distance < closestDistance then
                    closestDistance = distance
                    closestCFrameValue = CFrameValue
                end
            end
        end
    end

    if closestCFrameValue then
        attachment.WorldCFrame = closestCFrameValue.Value
        local finalCFrame
        if closestCFrameValue.Parent.Parent.Name == "Back" or closestCFrameValue.Parent.Parent.Name == "Right" then
            finalCFrame = attachment.WorldCFrame + Vector3.new(0, fenceExtents.Y / 2 + 0.5, 0) + attachment.WorldCFrame.LookVector * fenceExtents.Z / 2
        else
            finalCFrame = attachment.WorldCFrame + Vector3.new(0, fenceExtents.Y / 2 + 0.5, 0) + attachment.WorldCFrame.LookVector * -fenceExtents.Z / 2
        end
        cframeoffset = cframeoffset:Lerp(finalCFrame, dt * 15)
        fence:PivotTo(cframeoffset)
    else
        -- Handle the case when the mouse is outside the range
        -- Example: fence:PivotTo(originalPosition)
        -- Replace "originalPosition" with the appropriate value
    end
end)
1 Like

Ok so If I am understanding this code correctly, it basically finds the closestDistance and closestCFrameValue and then outside of if the raycast hit it checks if there is a closestCFrameValue and if there is it does all the placement logic?

Alright I used Gulp’s formatted code and then just added a new variable to keep track of the old cframe and when the mouse isnt near it then i just put it back to the old cframe

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