Is my Placement System good?

Hello

I was wondering if my placement system is good enough to exist, i’m not satisfied with it because I know that some really good games that I enjoyed in past like Miners Haven has like 1000+ lines of codes in their placement system

Here is how the module work:
module.place(player, (MODEL) object, folder where blocks will be stored, the part that u can place blocks on)

In my case it is:
module.place(game.Players.LocalPlayer, workspace.test, workspace.Blocks, workspace.Plot)
(Local Script)

Here is the module script:

local UIS = game:GetService("UserInputService")

local module = {}
	
	local canPlaceObject = false
	local objectToPlace = nil
	local objectPlaced = false
	
	local placing = false
	
	function snapToGrid(position)
		return Vector3.new(
			math.floor(position.X/1+0.5)*1,
			position.Y,
			math.floor(position.Z/1+0.5)*1	
		)
	end
	
	function onMouseMove(plr,ray,object,objectsFolder,plot)
		local ignore = {object,plr.Character}
		local part,position = workspace:FindPartOnRayWithIgnoreList(ray,ignore,false,true)
		
		if part and (not objectPlaced and placing) and (object and object:FindFirstChild("PLACING")) then
			if (part==plot or part:IsDescendantOf(plot)) or part:IsDescendantOf(objectsFolder) then
				local newPosition  = snapToGrid(position)
				object:MoveTo(newPosition)
				
				canPlaceObject = true
			else
				canPlaceObject = false
			end
		else
			return false
		end
	end
	function onMouseClick(object,objectDATA)
		if canPlaceObject and (not objectPlaced and placing) and (object and object:FindFirstChild("PLACING")) then
			for _,DATA in pairs(objectDATA) do
				local block = DATA[1]
				local transparency = DATA[2]
				local canCollide = DATA[3]
				
				block.Transparency = transparency
				block.CanCollide = canCollide
			end
			object:FindFirstChild("PLACING"):Destroy()
			
			objectPlaced = true
			placing = false
		else
			return false
		end
	end
	
	function rotateRequest(object)
		if placing and (object and object:FindFirstChild("PLACING")) then
			local newCFrame = object:GetPrimaryPartCFrame() * CFrame.fromEulerAnglesXYZ(0,math.rad(90),0)
			object:SetPrimaryPartCFrame(newCFrame)
		else
			return false
		end
	end
	
	function cancelRequest(object)
		if placing and (object and object:FindFirstChild("PLACING")) then
			canPlaceObject = false
			objectPlaced = true
			objectToPlace = nil
			placing = false
			
			object:Destroy()
		end
	end

	function module.place(plr,object,objectsFolder,plot)
		objectToPlace = object
		
		local function placeRequest(plr,object,objectsFolder,plot)
			placing = true
			objectPlaced = false
				
			local newObject = object:Clone()
			newObject.Parent = objectsFolder
				
			local newObjectPLACING = Instance.new("Folder",newObject)
			newObjectPLACING.Name = "PLACING"
				
			local mouse = plr:GetMouse()
			mouse.TargetFilter = newObject
				
			local newObjectDATA = {}
			for _,object in pairs(newObject:GetChildren()) do
				if object:IsA("Part") or object:IsA("MeshPart") or object:IsA("UnionOperation") then
					table.insert(newObjectDATA,{object,object.Transparency,object.CanCollide})
					object.Transparency = 0.5
					object.CanCollide = false
				end
			end
				
			mouse.Move:Connect(function()
				if placing then
					local ray = Ray.new(mouse.Hit.p+Vector3.new(0,100,0),Vector3.new(0,-1000,0))
					onMouseMove(plr,ray,newObject,objectsFolder,plot)
				else
					return false
				end
			end)
			mouse.Button1Up:Connect(function()
				if placing then
					onMouseClick(newObject,newObjectDATA)
				else
					return false
				end
			end)
				
			UIS.InputBegan:Connect(function(key)
				if key.KeyCode==Enum.KeyCode.R then
					rotateRequest(newObject)
				elseif key.KeyCode==Enum.KeyCode.F then
					cancelRequest(newObject)
				end
			end)
		end
		
		placeRequest(plr,object,objectsFolder,plot)
		repeat wait()
			repeat wait() until not placing
			if objectToPlace then
				placeRequest(plr,object,objectsFolder,plot)
			end
		until objectToPlace ~= object
	end

return module

There is a video:

Can you guys give me an advice, what can I change, because I feel that this code could be scripted better

Sorry for my bad englisch

3 Likes

Frankly, your code seems decently thought out, but I would suggest from a user perspective tweening the object’s rotation when you press R instead of snapping in:

function rotateRequest(object)

Good luck! :octopus: :slight_smile:

2 Likes

Okay, thank you :slightly_smiling_face: I already have an idea how to do it :grinning:

2 Likes