Hey! I recently used @EgoMoose 's grid placement tutorial and came across an issue.
In the tutorial, he only includes how to put parts on one particular side (left,right,top,bottom,front or back) but not all at the same time.
I’ve tried doing this by myself, but it looks like it’s having seizures
Here’s the script:
local Ogblock = script:WaitForChild("Block")
local plr = game:GetService("Players").LocalPlayer
local mouse = plr:GetMouse()
local equipped
local model
local origCanvas
local canvas
local rotation = 0
local function getCanvas()
local canvasSize = canvas.Size
local up = Vector3.new(0, 1, 0)
local back = -Vector3.FromNormalId(Enum.NormalId.Top)
local dot = back:Dot(Vector3.new(0, 1, 0))
local axis = (math.abs(dot) == 1) and Vector3.new(-dot, 0, 0) or up
local right = CFrame.fromAxisAngle(axis, math.pi/2) * back
local top = back:Cross(right).Unit
local cf = canvas.CFrame * CFrame.fromMatrix(-back*canvasSize/2, right, top, back)
local size = Vector2.new((canvasSize * right).magnitude, (canvasSize * top).Magnitude)
return cf, size
end
local function isColliding(part)
local isColliding = false
for i, v in pairs(canvas:GetChildren()) do
if v.Position == part.Position then
isColliding = true
end
end
return isColliding
end
local function getCframe(block,position,rot)
local cf, size = getCanvas()
local modelSize = CFrame.fromEulerAnglesYXZ(0, rot, 0) * model.Size
modelSize = Vector3.new(math.abs(modelSize.x), math.abs(modelSize.y), math.abs(modelSize.z))
local lpos = cf:pointToObjectSpace(position);
local size2 = (size - Vector2.new(modelSize.x, modelSize.z))/2
local x = math.clamp(lpos.x, -size2.x, size2.x);
local y = math.clamp(lpos.y, -size2.y, size2.y);
local g = 4
if (g > 0) then
x = math.sign(x)*((math.abs(x) - math.abs(x) % g) + (size2.x % g))
y = math.sign(y)*((math.abs(y) - math.abs(y) % g) + (size2.y % g))
end
return cf * CFrame.new(x, y, -modelSize.y / 2) * CFrame.Angles(-math.pi / 2, rot, 0)
end
local function onRotate(actionName, userInputState, input)
if equipped then
if (userInputState == Enum.UserInputState.Begin) then
rotation = rotation + math.pi / 2
end
end
end
local function onPlace(actionName, userInputState, input)
if equipped then
if (userInputState == Enum.UserInputState.Begin) then
local cf = getCframe(model, mouse.Hit.Position, rotation)
local tbl = {
Color = plr:GetAttribute("Color");
Material = plr:GetAttribute("Material")
}
game:GetService("ReplicatedStorage").Place:FireServer(tbl, cf, isColliding(model))
canvas = origCanvas
print(canvas)
end
end
end
game:GetService("ContextActionService"):BindAction("rotate", onRotate, false, Enum.KeyCode.R)
game:GetService("ContextActionService"):BindAction("place", onPlace, false, Enum.UserInputType.MouseButton1)
game:GetService("RunService").Heartbeat:Connect(function()
if equipped == true then
task.wait(1)
if mouse.Target then
if mouse.Target.Parent == canvas then
if canvas ~= mouse.Target then canvas = mouse.Target end
else
if canvas ~= origCanvas then canvas = origCanvas end
end
end
local cf = getCframe(model, mouse.Hit.Position, rotation)
if model.CFrame ~= cf then model.CFrame = cf end
end
end)
game:GetService("ReplicatedStorage"):WaitForChild("Enable").Event:Connect(function(bool)
if type(bool) == "boolean" and bool == true then
-- when plr begins build mode
if model then model:Destroy() end
model = Ogblock:Clone()
model.Color = plr:GetAttribute("Color")
model.Material = Enum.Material[plr:GetAttribute("Material")]
model.Name = plr.Name
model.Parent = workspace
canvas = workspace.Plots[plr.Name]
origCanvas = workspace.Plots[plr.Name]
equipped = true
task.delay(.1,function()
-- sometimes it glitches so this is to prevent said glitch
if model.Color ~= plr:GetAttribute("Color") then
model.Color = plr:GetAttribute("Color")
model.Material = Enum.Material[plr:GetAttribute("Material")]
end
end)
else
--- when plr cancels build mode
if model then model:Destroy() end
equipped = false
end
end)