Placement System not working correctly

Note about the code: I will be putting print statements all over the place to see what is going on.

Don’t bully me, but I had to use TheDevKing’s placement system tutorial for this. I will probably be doing some changed to his code.

So, his placement system couldn’t really work properly, so I looked in the code and found out that :FindPartOnRayWithIgnoreList() was deprecated.

I replaced it with some other function. The placement system still doesn’t really work as planned.

LocalScript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaceStructure = ReplicatedStorage:WaitForChild("PlaceStructure")
local Structures = ReplicatedStorage:WaitForChild("Structures")

local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local player = game.Players.LocalPlayer
local StructureFrame = script.Parent.StructureFrame
local char = player.Character or player.Character:Wait()
local HumanoidRootPart = char:WaitForChild("HumanoidRootPart")

local mouse = player:GetMouse()

local yBuildingOffset = 5
local maxPlacingDistance = 50
local rKeyIsPressed = false
local placingStructure = false

local Camera = workspace.CurrentCamera

local function GetMousePosition3D()
	local raycastParams = RaycastParams.new()
	local mousePos2d = UIS:GetMouseLocation()
	local raycastResult = workspace:Raycast(Camera.CFrame.Position, Camera:ViewportPointToRay(mousePos2d.X, mousePos2d.Y).Direction.unit * 5000)
	return raycastResult
end

for _, structureButton in pairs(StructureFrame:GetChildren()) do
	if structureButton:IsA("TextButton") then
		structureButton.MouseButton1Up:Connect(function()
			StructureFrame.Visible = false

			local yOrientation = 0
			local goodToPlace = false
			local placedStructure

			if not placingStructure then
				placingStructure = true

				local clientStructure = Structures:FindFirstChild(structureButton.Name):Clone()
				clientStructure.BrickColor = BrickColor.new("Forest green")
				clientStructure.Material = "Neon"
				clientStructure.CanCollide = false
				clientStructure.Parent = game.Workspace

				local startingCFrame = CFrame.new(0, 2.5, -15)
				clientStructure.CFrame = HumanoidRootPart.CFrame:ToWorldSpace(startingCFrame)

				RunService.RenderStepped:Connect(function()
					--local ignoreList = {clientStructure, char}
					local raycastResult = GetMousePosition3D()
					local hit, position = raycastResult.Instance, raycastResult.Position

					if hit and (hit.Name == "Baseplate") and (HumanoidRootPart.Position - clientStructure.Position).Magnitude < maxPlacingDistance then
						goodToPlace = true
						clientStructure.BrickColor = BrickColor.new("Forest green")
					else
						goodToPlace = false
						clientStructure.BrickColor = BrickColor.new("Crimson")
					end

					local newAnglesCFrame = CFrame.Angles(0, math.rad(yOrientation), 0)
					local newCFrame = CFrame.new(position.X, position.Y + yBuildingOffset, position.Z)
					clientStructure.CFrame = newCFrame * newCFrame
				end)

				UIS.InputBegan:Connect(function(input)
					if input.KeyCode == Enum.KeyCode.R then
						rKeyIsPressed = true

						local rotationSpeed = 5
						while rKeyIsPressed do
							wait()
							if placingStructure == true then
								yOrientation = yOrientation + rotationSpeed
								clientStructure.Orientation = Vector3.new(0, yOrientation, 0)
							end
						end
					end
				end)

				UIS.InputEnded:Connect(function(input)
					if input.KeyCode == Enum.KeyCode.R then
						rKeyIsPressed = false
					end
				end)

				UIS.InputBegan:Connect(function(input)
					if input.UserInputType == Enum.UserInputType.MouseButton1 then
						if placingStructure == true then
							if goodToPlace == true then
								local structureCFrame = clientStructure.CFrame
								placedStructure = PlaceStructure:InvokeServer(clientStructure.Name, structureCFrame)

								if placedStructure == true then
									placingStructure = false
									clientStructure:Destroy()
									StructureFrame.Visible = true
								end
							end
						end
					end
				end)
			end
		end)
	end
end

Script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlaceStructure = ReplicatedStorage:WaitForChild("PlaceStructure")
local Structures = ReplicatedStorage:WaitForChild("Structures")

PlaceStructure.OnServerInvoke = function(player, StructureName, StructureCFrame)
	local crafted
	local realStructure = Structures:FindFirstChild(StructureName):Clone()

	if realStructure then
		realStructure.CFrame = StructureCFrame
		realStructure.Parent = workspace
		crafted = true
	else
		crafted = false
	end

	return crafted
end

An error I’m getting is

attempt to index nil with Instance

So apparently raycastResult is nil even though I can place?

Some known bugs:

  • The thing I’m placing isn’t where the mouse is
  • If I place a cube then a sphere, the sphere turns into a cube
  • When I press the R key it doesn’t rotate
  • Sometimes it does rotate but I can’t see
  • When it does rotate I see a bunch of duplicates
  • And that error
1 Like

Do you still need help? Just asking might be able to help.

When I saw this script I tried to make my version and I think it works great.

I can help you