Keep erroring when trying to place items

Hi, I want to be able to actually place items but for some reason i keep getting this error:
15:35:38.262 Players.MonsterStepDa.PlayerGui.BuildConfigs.PlacementGuiScript:168: attempt to call a nil value - Client - PlacementGuiScript:168
15:35:38.262 Stack Begin - Studio
15:35:38.262 Script ‘Players.MonsterStepDa.PlayerGui.BuildConfigs.PlacementGuiScript’, Line 168 - Studio - PlacementGuiScript:168
15:35:38.262 Stack End - Studio

This is the script is refers too.

-- Client-Side Script: PlacementGuiScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local user = Players.LocalPlayer
local placementEvent = ReplicatedStorage:WaitForChild("PlacementEvent")
local getPlotFunction = ReplicatedStorage:WaitForChild("GetPlotFunction")  -- Add this line

local leaderstats = user:WaitForChild("leaderstats")  -- Wait for leaderstats to be available
local moneyValue = leaderstats:WaitForChild("Money")  -- Wait for Money to be available

local getSetMoney = ReplicatedStorage:WaitForChild("GetSetMoney")

-- Function to handle leaderboard setup
local function handleLeaderboardSetup()
	
end

local leaderboardSetupEvent = ReplicatedStorage:WaitForChild("LeaderboardSetupEvent", 5)
if leaderboardSetupEvent then
	leaderboardSetupEvent.OnClientEvent:Connect(handleLeaderboardSetup)
else
	
end

local buildConfigs = script.Parent
local blocksShowcase = buildConfigs:WaitForChild("BlocksShowcase")
local scrollFrame = blocksShowcase:WaitForChild("ScrollFrame")
local openGuiButton = buildConfigs:WaitForChild("OpenGui")

local closeButton = blocksShowcase:FindFirstChild("Close")

local placementEvent = ReplicatedStorage:WaitForChild("PlacementEvent")

local selectedBlock = nil
local previewBlock = nil
local isPreviewing = false

local function startPreview(selectedBlockModel)
	if not selectedBlockModel then
		warn("No block selected for preview")
		return
	end

	if previewBlock then
		previewBlock:Destroy()  -- Remove any existing preview block
	end

	previewBlock = selectedBlockModel:Clone()
	previewBlock.Parent = workspace  -- Place it in the workspace
	for _, part in pairs(previewBlock:GetDescendants()) do
		if part:IsA("BasePart") then
			part.Transparency = 0.5  -- Making the block semi-transparent
			part.CanCollide = false  -- Ensure it doesn't collide with other objects
		end
	end

	isPreviewing = true  -- Set the previewing flag
end

local function updatePreview()
	if isPreviewing and previewBlock then
		local mousePosition = UserInputService:GetMouseLocation()
		local camera = workspace.CurrentCamera
		local ray = camera:ScreenPointToRay(mousePosition.X, mousePosition.Y)
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {user.Character, previewBlock}
		raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

		local raycastResult = workspace:Raycast(ray.Origin, ray.Direction * 500, raycastParams) -- Adjust the distance as needed
		if raycastResult then
			local hitPosition = raycastResult.Position
			local placementPosition = hitPosition + Vector3.new(0, previewBlock.PrimaryPart.Size.Y / 2, 0) -- Adjust the height offset as needed
			previewBlock:SetPrimaryPartCFrame(CFrame.new(placementPosition))
		end
	end
end



game:GetService("RunService").Heartbeat:Connect(updatePreview)
local placeItemButton = buildConfigs:WaitForChild("PlaceItemButton")  -- Adjust according to its actual location
local cancelButton = buildConfigs:WaitForChild("CancelButton")  -- Assuming you have a CancelButton in your UI

local function handlePlaceItemButtonClick()
	if selectedBlock then
		local plotName = getPlotFunction:InvokeServer()
		if plotName then
			placementEvent:FireServer("place", selectedBlock.Name, plotName)
			selectedBlock = nil  -- Reset selected block after placing
			placeItemButton.Visible = false  -- Hide the "Place Item" button
		else
			warn("No plot found for the player")
		end
	else
		warn("No block selected for placement")
	end
end

if placeItemButton then
	placeItemButton.MouseButton1Click:Connect(handlePlaceItemButtonClick)
end
local function handleCancelButtonClick()
	if isPreviewing and previewBlock then
		previewBlock:Destroy()
		previewBlock = nil
		isPreviewing = false
		selectedBlock = nil
		placeItemButton.Visible = false
		cancelButton.Visible = false
	end
end

if cancelButton then
	cancelButton.MouseButton1Click:Connect(handleCancelButtonClick)
end
local function tryPlaceBlock()
	local currentMoney = getSetMoney:InvokeServer("get")
	local plotName = getPlotFunction:InvokeServer()
	if selectedBlock and currentMoney and plotName then
		local cost = selectedBlock:FindFirstChild("Cost")
		if cost and currentMoney >= cost.Value then
			-- Player has enough money, proceed with preview and placement
			placementEvent:FireServer("preview", selectedBlock.Name, plotName)
		else
			warn("Not enough money to place this block.")
		end
	else
		warn("Block, money, or plot information is missing.")
	end
end

local function finalizePlacement()
	if isPreviewing and previewBlock and selectedBlock then
		local position = previewBlock.PrimaryPart.Position
		local rotation = previewBlock.PrimaryPart.Orientation -- Assuming the block has a PrimaryPart

		-- Send the placement command with position and rotation
		placementEvent:FireServer("place", selectedBlock.Name, position, rotation)

		-- Cleanup
		previewBlock:Destroy()
		previewBlock = nil
		isPreviewing = false
		selectedBlock = nil

		if placeItemButton then
			placeItemButton.Visible = false
		else
			warn("placeItemButton not found")
		end

		if cancelButton then
			cancelButton.Visible = false
		else
			warn("cancelButton not found")
		end
	end
end

-- Connect this function to wherever you want to listen for the mouse movements or touch
updatePreview()

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then return end  -- Ignore processed inputs
	if input.KeyCode == Enum.KeyCode.E then  -- Replace with your desired key
		placeBlock()
	end
end)
-- Function to toggle BlocksShowcase GUI visibility
local function toggleGui()
	blocksShowcase.Visible = not blocksShowcase.Visible
end

-- Function to close BlocksShowcase GUI
local function closeGui()
	blocksShowcase.Visible = false
end

-- Create and configure UIGridLayout
local gridLayout = Instance.new("UIGridLayout")
gridLayout.CellPadding = UDim2.new(0, 10, 0, 10)
gridLayout.CellSize = UDim2.new(0, 128, 0, 128)
gridLayout.FillDirection = Enum.FillDirection.Horizontal
gridLayout.SortOrder = Enum.SortOrder.LayoutOrder
gridLayout.Parent = scrollFrame

-- Populating blocks
for _, category in pairs({"Builds", "Decoration", "Interior"}) do
	local categoryFolder = ReplicatedStorage:FindFirstChild("Builder"):FindFirstChild(category)
	if categoryFolder then
		
		for _, block in pairs(categoryFolder:GetChildren()) do
			if block:IsA("Model") then
				local cost = block:FindFirstChild("Cost")
				if cost then
					
					local blockButton = Instance.new("TextButton")
					blockButton.Size = UDim2.new(0, 128, 0, 128)
					blockButton.BackgroundColor3 = Color3.fromRGB(236,236,236)  -- Background color of the button
					blockButton.Text = ""
					blockButton.TextColor3 = Color3.fromRGB(0, 0, 0)  -- Text color of the button (not applicable here since Text is empty)
					blockButton.Parent = scrollFrame

					local viewport = Instance.new("ViewportFrame")
					viewport.Size = UDim2.new(1, 0, 1, 0)  -- Fill the entire TextButton
					viewport.Parent = blockButton
					viewport.BackgroundColor3 = Color3.fromRGB(236,236,236)

					local camera = Instance.new("Camera")
					camera.Parent = viewport
					viewport.CurrentCamera = camera
					camera.CameraType = Enum.CameraType.Scriptable
					if block.PrimaryPart then
						camera.CFrame = CFrame.new(block.PrimaryPart.Position + Vector3.new(5, 5, 5), block.PrimaryPart.Position)
					end
					
					local rotationCFrame = CFrame.Angles(0, math.rad(10), 0)  -- Rotating 10 degrees around Y-axis

					if block.PrimaryPart then
						local targetPosition = block.PrimaryPart.Position
						local originalPosition = targetPosition + Vector3.new(5, 5, 5)
						local originalCFrame = CFrame.new(originalPosition, targetPosition)

						-- Apply rotation to the original CFrame and re-adjust the position
						local rotatedCFrame = originalCFrame * rotationCFrame
						local newPosition = rotatedCFrame.Position
						camera.CFrame = CFrame.new(newPosition, targetPosition)
					end

					local costLabel = Instance.new("TextLabel")
					costLabel.Size = UDim2.new(1, 0, 0, 20)
					costLabel.Position = UDim2.new(0, 0, 1, -20)
					costLabel.Text = " " .. block.Name .. " | " .. cost.Value
					costLabel.TextColor3 = Color3.fromRGB(255, 255, 255)  -- Text color of the label
					costLabel.BackgroundColor3 = Color3.fromRGB(85, 85, 0)  -- Background color of the label
					costLabel.Parent = blockButton

					local displayBlock = block:Clone()
					displayBlock.Parent = viewport

					-- Add rotation here
					local rotationCFrame = CFrame.Angles(0, math.rad(210), 0)  -- Rotating 10 degrees around Y-axis
					displayBlock:SetPrimaryPartCFrame(displayBlock.PrimaryPart.CFrame * rotationCFrame)
					local currentlySelectedButton = nil
					blockButton.MouseButton1Click:Connect(function()
						selectedBlock = block
						startPreview(selectedBlock)  -- Start the preview (ensure this function is defined correctly)
						placeItemButton.Visible = true  -- Show the "Place Item" button
						blocksShowcase.Visible = false  -- Close the blocksShowcase GUI
						if currentlySelectedButton then
							-- Reset the appearance of the previously selected button
							currentlySelectedButton.BackgroundColor3 = Color3.fromRGB(236, 236, 236)
						end
						-- Change the appearance of the current button to indicate selection
						blockButton.BackgroundColor3 = Color3.fromRGB(210, 210, 210)
						currentlySelectedButton = blockButton
					end)
				else
					
				end
			else
				
			end
		end
	else
		
	end
end

UserInputService.InputBegan:Connect(function(input, isProcessed)
	if isProcessed then return end
	if input.KeyCode == Enum.KeyCode.Q then
		handleCancelButtonClick()
	end
end)


-- Connect the OpenGui button to toggle GUI
if openGuiButton then
	openGuiButton.MouseButton1Click:Connect(toggleGui)
end

-- Connect the Close button to close GUI
if closeButton then
	closeButton.MouseButton1Click:Connect(closeGui)
end

-- Optionally, you can use UserInputService for touch support
if UserInputService then
	UserInputService.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.Touch and input.UserInputState == Enum.UserInputState.Begin then
			local touchPos = input.Position
			local guiPos = openGuiButton.AbsolutePosition
			local guiSize = openGuiButton.AbsoluteSize

			if touchPos.x >= guiPos.x and touchPos.x <= guiPos.x + guiSize.x and touchPos.y >= guiPos.y and touchPos.y <= guiPos.y + guiSize.y then
				toggleGui()
			end
		end
	end)
else
	
end
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local restoreEvent = ReplicatedStorage:WaitForChild("restoreEvent")

local restoreButton = script.Parent:FindFirstChild("RestoreButton")  -- Replace with the actual path to your Restore button

if restoreButton then
	restoreButton.MouseButton1Click:Connect(function()
		restoreEvent:FireServer()
	end)
end

Line 168 has a red line under it. so not sure what it means. Please see screenshot i’ve added. If anyone can help me figure out what is wrong I would be greatfull.

It means there is no function called PlaceBlock

There is no function called placeBlock()
you probably wanted to do tryPlaceBlock()

1 Like

if i fixed the error please mark it as solution

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