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.