Help With my Grid System

I’ve been working on a building game, this game has a custom grid system I made. But I’ve come across an issue recently, where wedges have bugged placement.

Basically, what I mean by this, is that when the player rotates a wedge, it errors the building system. It causes objects to be placed in the wrong positions.

This is my code:

--// Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputs = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

--// Variables
local Blocks = ReplicatedStorage:WaitForChild("Blocks")
local Events = ReplicatedStorage:WaitForChild("Events")

local WorldData = workspace:WaitForChild("WorldData")

local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

local PlayerUI = Player.PlayerGui:WaitForChild("PlayerUI")
local BlockProperties = PlayerUI:WaitForChild("BlockProperties")

local CurrentPlaceholder = nil

Player:SetAttribute("EditMode", "BUILD")
Player:SetAttribute("BlockShape", "Block")
Player:SetAttribute("BlockColor", BrickColor.White())
Player:SetAttribute("BlockMaterial", Enum.Material.Plastic)

BlockProperties.Visible = false

local ClickDelay = 0.05
local OnDelay = false

task.wait(1)

local function CreatePlaceholder()
		
	if CurrentPlaceholder ~= nil then

		CurrentPlaceholder:Destroy()
		CurrentPlaceholder = nil

	end
	
	local Block = Blocks:FindFirstChild(Player:GetAttribute("BlockShape"))
	if Block then
		
		Block = Block:Clone()
		
		Block.Transparency = 0.5
		Block.CanCollide = false
		
		Block.Parent = workspace
		
		CurrentPlaceholder = Block
		
	end
	
end
local function ReturnCalculated(Offset)
	
	local Target = Mouse.Target
	if Target then
		
		local cf = CFrame.new(Target.Position + Offset)
		local convertedCF = Target.CFrame:ToWorldSpace(cf)
	
		--[[
		local cf = CFrame.new(Target.Position + Offset)
		local convertedCF = Target.CFrame:ToObjectSpace(cf)
		]]

		return convertedCF
		
	end
	
end
local function CalculatePosition(targetSurface)
	
	local GridStep = 3
	if targetSurface == "Front" then
		
		local convertedCF = ReturnCalculated(Vector3.new(0, 0, -GridStep))
		return convertedCF
		
	elseif targetSurface == "Back" then
		
		local convertedCF = ReturnCalculated(Vector3.new(0, 0, GridStep))
		return convertedCF
		
	elseif targetSurface == "Left" then

		local convertedCF = ReturnCalculated(Vector3.new(-GridStep, 0, 0))
		return convertedCF
		
	elseif targetSurface == "Right" then

		local convertedCF = ReturnCalculated(Vector3.new(GridStep, 0, 0))
		return convertedCF
		
	elseif targetSurface == "Top" then

		local convertedCF = ReturnCalculated(Vector3.new(0, GridStep, 0))
		return convertedCF
		
	elseif targetSurface == "Bottom" then

		local convertedCF = ReturnCalculated(Vector3.new(0, -GridStep, 0))
		return convertedCF
		
	end
	
end

Mouse.Button1Down:Connect(function()
	
	if WorldData.Permissions:FindFirstChild(Player.Name) then

		if Mouse.Target ~= nil then

			if OnDelay == false then

				OnDelay = true

				if Mouse.Target.Parent == workspace.Blocks then
					
					script.Highlight.Adornee = nil
					if Player:GetAttribute("EditMode") == "BUILD" then

						local BlockData = {
							name = CurrentPlaceholder.Name,
							cframe = CurrentPlaceholder.CFrame,
							color = Player:GetAttribute("BlockColor"),
							material = Player:GetAttribute("BlockMaterial"),
						}

						script.Place:Play()
						Events.BlockServer:FireServer("BUILD", BlockData)

					elseif Player:GetAttribute("EditMode") == "DELETE" then

						local BlockData = {
							target = Mouse.Target,
						}

						Events.BlockServer:FireServer("DELETE", BlockData)
						
					elseif Player:GetAttribute("EditMode") == "PAINT" then

						local BlockData = {
							target = Mouse.Target,
							color = Player:GetAttribute("BlockColor"),
							material = Player:GetAttribute("BlockMaterial"),
						}

						Events.BlockServer:FireServer("PAINT", BlockData)

					end

				end

				task.wait(ClickDelay)

				OnDelay = false

			end

		end

	end
	
end)
UserInputs.InputBegan:Connect(function(input, gP)
	
	if WorldData.Permissions:FindFirstChild(Player.Name) then
		
		if WorldData.Permissions[Player.Name].Value < 3 then
			
			if not gP then

				if input.KeyCode == Enum.KeyCode.Q then

					if Player:GetAttribute("EditMode") == "BUILD" then

						Player:SetAttribute("EditMode", "PAINT")

					elseif Player:GetAttribute("EditMode") == "PAINT" then

						Player:SetAttribute("EditMode", "DELETE")
						
					elseif Player:GetAttribute("EditMode") == "DELETE" then

						Player:SetAttribute("EditMode", "VIEWER")
						
					elseif Player:GetAttribute("EditMode") == "VIEWER" then

						Player:SetAttribute("EditMode", "BUILD")

					end

				elseif input.KeyCode == Enum.KeyCode.R then

					if CurrentPlaceholder then

						CurrentPlaceholder.CFrame *= CFrame.Angles(0, math.rad(90), 0)

					end

				elseif input.KeyCode == Enum.KeyCode.T then

					if CurrentPlaceholder then

						CurrentPlaceholder.CFrame *= CFrame.Angles(0, 0, math.rad(90))

					end

				elseif input.KeyCode == Enum.KeyCode.LeftAlt then

					if Mouse.Target ~= nil then

						Player:SetAttribute("BlockColor", Mouse.Target.BrickColor)
						Player:SetAttribute("BlockMaterial", Mouse.Target.Material)

					end

				end

			end
			
		end
		
	end
	
end)

CreatePlaceholder()
Mouse.TargetFilter = CurrentPlaceholder
RunService.RenderStepped:Connect(function()
	
	if WorldData.Permissions:FindFirstChild(Player.Name) then
		
		if WorldData.Permissions[Player.Name].Value < 3 then
			
			PlayerUI.Mode.Visible = true
			Player:GetAttributeChangedSignal("BlockShape"):Connect(function()

				CreatePlaceholder()
				Mouse.TargetFilter = CurrentPlaceholder

			end)
			
			-- UI
			local EditMode = Player:GetAttribute("EditMode")
			PlayerUI.Mode.Text = EditMode .. " MODE"

			BlockProperties.List.Color.Frame.BackgroundColor3 = Player:GetAttribute("BlockColor").Color
			BlockProperties.List.Materials.Frame.ViewportFrame.Block.Material = Player:GetAttribute("BlockMaterial")
			BlockProperties.List.Shape.Display.Text = Player:GetAttribute("BlockShape")

			if Mouse.Target ~= nil then

				if Mouse.Target:FindFirstChild("SIGN") then

					PlayerUI.Sign.Text = Mouse.Target.SIGN.Value
					PlayerUI.Sign.Visible = true

				else

					PlayerUI.Sign.Text = ""
					PlayerUI.Sign.Visible = false

				end

			else

				PlayerUI.Sign.Text = ""
				PlayerUI.Sign.Visible = false

			end

			-- BUILD STUFF
			CurrentPlaceholder.BrickColor = Player:GetAttribute("BlockColor")
			CurrentPlaceholder.Material = Player:GetAttribute("BlockMaterial")
			if EditMode == "BUILD" then

				BlockProperties.Visible = true

				script.Highlight.OutlineColor = Color3.fromRGB(0, 130, 255)
				script.Highlight.Adornee = nil
				CurrentPlaceholder.Transparency = 0.25
				if Mouse.Target ~= nil then

					if Mouse.Target.Parent == workspace.Blocks then

						local posOffset = CalculatePosition(Mouse.TargetSurface.Name)
						CurrentPlaceholder.CFrame = posOffset

					end

				else

					CurrentPlaceholder.Position = Vector3.new(0, 0, 0)
					CurrentPlaceholder.Transparency = 1

				end

			elseif EditMode == "DELETE" then

				BlockProperties.Visible = false

				script.Highlight.OutlineColor = Color3.fromRGB(255, 0, 0)
				CurrentPlaceholder.Transparency = 1
				if Mouse.Target ~= nil then

					if Mouse.Target.Parent == workspace.Blocks then

						script.Highlight.Adornee = Mouse.Target

					else

						script.Highlight.Adornee = nil

					end

				else

					script.Highlight.Adornee = nil

				end

			elseif EditMode == "PAINT" then

				BlockProperties.Visible = true

				script.Highlight.OutlineColor = Color3.fromRGB(0, 200, 0)
				CurrentPlaceholder.Transparency = 1
				if Mouse.Target ~= nil then

					if Mouse.Target.Parent == workspace.Blocks then

						script.Highlight.Adornee = Mouse.Target

					else

						script.Highlight.Adornee = nil

					end

				else

					script.Highlight.Adornee = nil

				end
				
			else
				
				PlayerUI.Mode.Visible = false
				BlockProperties.Visible = false

				CurrentPlaceholder.Transparency = 1
				script.Highlight.Adornee = nil
				
			end
			
		else

			PlayerUI.Mode.Visible = false
			BlockProperties.Visible = false

			CurrentPlaceholder.Transparency = 1
			script.Highlight.Adornee = nil
			
		end
		
	end
	
end)

The functions that calculate placeholder movement are ReturnCalculated and CalculatePosition.

If you are trying to help, please include code examples and/or explanations.

Edit: Incase you were wondering, I’ve tried to use :ToObjectSpace and :ToWorldSpace, but it just caused the placeholder to move by 2 block steps. And, the blocks are 3, 3, 3.

Sorry, I managed to get it working. I just had to play around with the movement stuff.

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