How do I stop the ghost-part from interfering? How do I get the mouse to Ignore it?

I’m attempting to create a building system for my upcoming game, but I’ve run into a bit of a problem that is difficult to fix. This is an attachment-based system, and I managed to create this:

That part is the ghost part that is shown before you place something to let you know where it’s going to be placed. The problem here is easily noticed — it’s choppy, and I know why. The ghost part is only activated when the mouse.Target is the building plate. When the ghost part is created, the mouse.Target then becomes the ghost part. This creates a loop of destroying and cloning, and I have no idea how to fix this.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local mouse = Players.LocalPlayer:GetMouse()

local plates = workspace.Plates
local blocks = ReplicatedStorage.Blocks

local buildingMode = true
local selectedBlock = "RedNormal"

function createGhostPart(blockType)
	local ghostPart = blocks:FindFirstChild(blockType):Clone()
	ghostPart.Transparency = 0.5
	ghostPart.Name = "ghostPart"
	ghostPart.CanCollide = false
	return ghostPart
end

while wait(0.05) and buildingMode do
	if mouse.Target ~= nil and mouse.Target.Parent == plates and mouse.TargetSurface == Enum.NormalId.Top then
		local plate = mouse.Target
		local mouseCFrame = mouse.Hit
		local mousePosition = mouseCFrame.Position
		local nearestAttachment = nil
		for _,v in pairs(plate:GetChildren()) do
			if v.ClassName == "Attachment" then
				if not nearestAttachment then
					nearestAttachment = v
				else
					local current = (nearestAttachment.WorldPosition - mousePosition).magnitude
					local new = (v.WorldPosition - mousePosition).magnitude
					if new < current then
						nearestAttachment = v
					end
				end
			end
		end
		print(1)
		if not workspace.Terrain:FindFirstChild("ghostPart") then
			print(2)
			ghostPart = createGhostPart(selectedBlock)
			ghostPart.Parent = workspace.Terrain
		else
			ghostPart = workspace.Terrain:FindFirstChild("ghostPart")
		end
		ghostPart.Position = nearestAttachment.WorldPosition + Vector3.new(0,1.5,0)
	elseif workspace.Terrain:FindFirstChild("ghostPart") then
		workspace.Terrain:FindFirstChild("ghostPart"):Destroy()	
	end
end

(I apologize for the messy code)

I am unable to figure out a method of fixing this.

Thanks for your help! I’d also like it if you could give feedback on how I wrote this.

You would use Mouse.TargetFilter to ignore a part.

2 Likes