Items placement is going too far away not in the place i want it

Hi, I have a placement system however when trying to place items it’s not actually placing them where users move thier cursor or tap on the screen it’s placing them half way across the other side of the world. Could you assist on helping me fix why this is happening. I’ve gone through and it looks correct to me but its not :frowning:

--placement event for blocks
local function onPlaceEvent(player, blockName, position, rotation)
	print("onPlaceEvent triggered", player.Name, blockName, position, rotation)
	print("PlaceEvent received from client:", player.Name, blockName, position, rotation)  -- Debug message
	-- Ensure position and rotation are valid before proceeding
	if not position or not rotation then
		warn("Position or rotation is nil for onPlaceEvent.")
		return
	end

	local plotIdentifier = playerPlots[player.UserId]
	if not plotIdentifier then
		warn("Plot identifier not found for the player.")
		return
	end

	local plot = game.Workspace.Plots:FindFirstChild(plotIdentifier)
	if not plot then
		warn("Plot not found.")
		return
	end

	local builder = ReplicatedStorage:FindFirstChild("Builder")
	local blockFound = findBlockInGroups(builder, blockName)
	if blockFound then
		local blockToPlace = blockFound:Clone()
		local targetPosition = plot.Position + Vector3.new(position.X, position.Y, position.Z)
		local targetRotation = CFrame.Angles(math.rad(rotation.X), math.rad(rotation.Y), math.rad(rotation.Z))
		local newCFrame = CFrame.new(targetPosition) * targetRotation

		blockToPlace:SetPrimaryPartCFrame(newCFrame)
		blockToPlace.Parent = plot

		-- Anchoring logic for Model or Part
		if blockToPlace:IsA("Model") then
			for _, part in pairs(blockToPlace:GetDescendants()) do
				if part:IsA("Part") then
					part.Anchored = true
				end
			end
		elseif blockToPlace:IsA("Part") then
			blockToPlace.Anchored = true
		end

		-- Update the player's blocks list
		if not playerBlocks[player.UserId] then
			playerBlocks[player.UserId] = {}
		end
		table.insert(playerBlocks[player.UserId], blockToPlace)

		-- Debug statements to check block status
		print("Block placed in plot:", blockToPlace, plot)
		print("Block position after placement:", blockToPlace.PrimaryPart.Position)
		print("Block parent after placement:", blockToPlace.Parent)
		print("Block placed successfully:", blockName)
		print("Block Anchored:", blockToPlace.PrimaryPart.Anchored)
		print("Block Transparency:", blockToPlace.PrimaryPart.Transparency)
		print("Block Position:", blockToPlace.PrimaryPart.Position)
		print("Block Parent:", blockToPlace.Parent)
		-- Wait and recheck
		wait(2) -- Wait for 2 seconds
		if blockToPlace and blockToPlace.Parent then
			print("Block still exists after 2 seconds")
			print("Block Position after 2 seconds:", blockToPlace.PrimaryPart.Position)
			print("Block Parent after 2 seconds:", blockToPlace.Parent)
		else
			print("Block disappeared after 2 seconds")
		end

		print("Block placed successfully:", blockName)
	else
		warn("Block not found in the groups:", blockName)
	end
end

placeEvent.OnServerEvent:Connect(onPlaceEvent)

that was the server side script and then this is the client script:


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()
	print("PlaceItemButton clicked")  -- Debug message
	if selectedBlock then
		local plotName = getPlotFunction:InvokeServer()  -- Get the plot name associated with the player
		print("Plot Name:", plotName)  -- Debug message
		if plotName and previewBlock and previewBlock.PrimaryPart then
			local position = previewBlock.PrimaryPart.Position
			local rotation = previewBlock.PrimaryPart.Orientation
			print("Sending placement data to server:", selectedBlock.Name, position, rotation)  -- Debug message
			-- Fire the PlaceEvent with the necessary information
			placeEvent:FireServer(selectedBlock.Name, position, rotation)

			-- Clean up after placing the block
			previewBlock:Destroy()
			previewBlock = nil
			isPreviewing = false
			selectedBlock = nil
			placeItemButton.Visible = false
			cancelButton.Visible = false
			print("Placement data sent to server.")
		else
			warn("No plot found or preview block is invalid.")
		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 placeEvent = ReplicatedStorage:WaitForChild("PlaceEvent")
local function finalizePlacement()
	if isPreviewing and previewBlock and selectedBlock then
		if previewBlock.PrimaryPart then
			local position = previewBlock.PrimaryPart.Position
			local rotation = previewBlock.PrimaryPart.Orientation -- Ensure these are not nil

			-- Debug print
			print("Attempting to place - Position:", position, "Rotation:", rotation)

			if position and rotation then
				placeEvent:FireServer(selectedBlock.Name, position, rotation)
				print("Sent to server - Position:", position, "Rotation:", rotation)
			else
				warn("Position or Rotation is nil")
			end
		else
			warn("previewBlock does not have a PrimaryPart set")
		end

		-- 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
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
		tryPlaceBlock()
	end
end)
-- Connect this function to wherever you want to listen for the mouse movements or touch
updatePreview()

any help with this would be awesome. Thank you.

Hello, I noticed this line in the ServerSide script,

local targetPosition = plot.Position + Vector3.new(position.X, position.Y, position.Z)

You haven’t declared the position variable on the serverside, therefore that may be the issue.

It’s placing it here -48.764, 1.05, -18.718, but should be placing it here 700.863, 9.267, 616.271

Not sure why though it says it’s passing the right info over on debug statements.

Could you expand on this for me please?