so i scripted an entire block placement system, but it seems like it is facing the player, i would like it’s bottom to face the floor and move in grids, here’s the tool script:
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local UIS = game:GetService('UserInputService')
local RS = game:GetService('ReplicatedStorage')
local tool = script.Parent
local Event = RS:WaitForChild('PlaceBlock')
local pos
equipped = false
local part = game.ReplicatedStorage.Blocks.Part:Clone()
-- Surface Detection
local function Surface(surface)
if surface.Name == "Top" then
pos = Vector3.new(0,4,0)
elseif surface.Name == "Bottom" then
pos = Vector3.new(0,-4,0)
elseif surface.Name == "Front" then
pos = Vector3.new(0,0,-4)
elseif surface.Name == "Back" then
pos = Vector3.new(0,0,4)
elseif surface.Name == "Left" then
pos = Vector3.new(-4,0,0)
elseif surface.Name == "Right" then
pos = Vector3.new(4,0,0)
end
return pos
end
local num = 1
local blocks = RS.Blocks:GetChildren()
local Block_Choice = blocks[1]
numberOfBlocks = #blocks
script.Parent.Activated:Connect(function()
local target = mouse.Target
if target then
local surface = mouse.TargetSurface
local pos = Surface(surface)
Event:FireServer(target,pos,Block_Choice)
end
end)
-- the selection part
mouse.Move:Connect(function()
if equipped == true then
part.Parent = workspace
mouse.TargetFilter = part
part.CFrame = mouse.Hit
end
end)
tool.Equipped:Connect(function()
equipped = true
end)
tool.Unequipped:Connect(function()
equipped = false
end)
Is it possible for you to show us a video of what’s happening.
As this is a visibility question its a bit hard to visualise from just part of the code.
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local UIS = game:GetService('UserInputService')
local RS = game:GetService('ReplicatedStorage')
local tool = script.Parent
local Event = RS:WaitForChild('PlaceBlock')
local pos
equipped = false
local part = game.ReplicatedStorage.Blocks.Part:Clone()
-- Surface Detection
local function Surface(surface)
if surface.Name == "Top" then
pos = Vector3.new(0,4,0)
elseif surface.Name == "Bottom" then
pos = Vector3.new(0,-4,0)
elseif surface.Name == "Front" then
pos = Vector3.new(0,0,-4)
elseif surface.Name == "Back" then
pos = Vector3.new(0,0,4)
elseif surface.Name == "Left" then
pos = Vector3.new(-4,0,0)
elseif surface.Name == "Right" then
pos = Vector3.new(4,0,0)
end
return pos
end
local num = 1
local blocks = RS.Blocks:GetChildren()
local Block_Choice = blocks[1]
numberOfBlocks = #blocks
script.Parent.Activated:Connect(function()
local target = mouse.Target
if target then
local surface = mouse.TargetSurface
local pos = Surface(surface)
Event:FireServer(target,pos,Block_Choice)
end
end)
-- the selection part
mouse.Move:Connect(function()
if equipped == true then
part.Parent = workspace
mouse.TargetFilter = part
local x = mouse.Hit.X
local y = mouse.Hit.Y
local z = mouse.Hit.Z
part.Position = Vector3.new(math.floor(x/4) * 4, math.floor(y/4) * 4, math.floor(z/4) * 4)
end
end)
tool.Equipped:Connect(function()
equipped = true
end)
tool.Unequipped:Connect(function()
equipped = false
end)
hmm i got two problems, it somehow don’t work when i am placing on the left side, but fine on right side, second problem is that i can place 2+ blocks inside one. here is the video of the first problem
now the slightly changed script
wait()
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local UIS = game:GetService('UserInputService')
local RS = game:GetService('ReplicatedStorage')
local tool = script.Parent
local Event = RS:WaitForChild('PlaceBlock')
local pos
equipped = false
local part = game.ReplicatedStorage.Blocks.Part:Clone()
part.Click:Destroy()
-- Surface Detection
local function Surface(surface)
if surface.Name == "Top" then
pos = Vector3.new(0,4,0)
elseif surface.Name == "Bottom" then
pos = Vector3.new(0,-4,0)
elseif surface.Name == "Front" then
pos = Vector3.new(0,0,-4)
elseif surface.Name == "Back" then
pos = Vector3.new(0,0,4)
elseif surface.Name == "Left" then
pos = Vector3.new(-4,0,0)
elseif surface.Name == "Right" then
pos = Vector3.new(4,0,0)
end
return pos
end
local num = 1
local blocks = RS.Blocks:GetChildren()
local Block_Choice = blocks[1]
numberOfBlocks = #blocks
script.Parent.Activated:Connect(function()
local target = mouse.Target
if target then
local surface = mouse.TargetSurface
local pos = part.Position--Surface(surface)
Event:FireServer(target,pos,Block_Choice)
end
end)
-- the selection part
mouse.Move:Connect(function()
if equipped == true then
part.CanCollide = false
part.Parent = workspace
mouse.TargetFilter = part
local x = mouse.Hit.X
local y = mouse.Hit.Y
local z = mouse.Hit.Z
part.Position = Vector3.new(math.floor(x/4) * 4, math.floor(y/4) * 4 + 2, math.floor(z/4) * 4)
end
end)
tool.Equipped:Connect(function()
equipped = true
part.Transparency = 0.5
end)
tool.Unequipped:Connect(function()
equipped = false
part.Transparency = 1
part.Position = Vector3.new(1,1,1)
end)
It’s the issue actually. When you click on the left, and I’d guess bottom and front sides as well, the mouse position is halfway between one block coordinate and another.
Since you’re using flooring to turn a mouse position that is probably not on a block coordinate into the nearest whole block coordinate, you get the same behavior regardless of if the mouse pos is +0.5 blocks from a block coordinate or -0.5 blocks. floor(0.5) = 0 and floor(-0.5) = -1. In both cases the number is smaller than the original, so e.g. if you click the left side of a block, the new block is placed half a block to the right of where you clicked, which is inside the existing block! When you click the right side, the resulting block is to the right of that, which is perfect since that’s where a block should actually be placed.
The solution is to not try to place blocks exactly at the mouse pos, but instead “half a block outwards from the mouse pos”. We can get the “outwards” direction as the normal of the surface that the mouse is pointing at, and (hopefully) fix the block placement like this:
local hitSurface = mouse.TargetSurface
local hitNormal = mouse.Target.CFrame:VectorToWorldSpace(Vector3.FromNormalId(hitSurface))
local buildPos = mouse.Hit + hitNormal * 2
local x = buildPos.X
local y = buildPos.Y
local z = buildPos.Z
part.Position = Vector3.new(math.floor(x/4) * 4, math.floor(y/4) * 4, math.floor(z/4) * 4)
huh it seems the part placing is action strangely, but you can still place two block in one place, i think i need to somehow detect if there is a part there already or not
hmm i tried making it detect if it is on the map or not, if it is then it goes up using the surface function, but it does not work at all, heres the script:
wait()
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local UIS = game:GetService('UserInputService')
local RS = game:GetService('ReplicatedStorage')
local tool = script.Parent
local Event = RS:WaitForChild('PlaceBlock')
local pos
equipped = false
local part = game.ReplicatedStorage.Blocks.Part:Clone()
part.Click:Destroy()
-- Surface Detection
local function Surface(surface)
if surface.Name == "Top" then
pos = Vector3.new(0,4,0)
elseif surface.Name == "Bottom" then
pos = Vector3.new(0,-4,0)
elseif surface.Name == "Front" then
pos = Vector3.new(0,0,-4)
elseif surface.Name == "Back" then
pos = Vector3.new(0,0,4)
elseif surface.Name == "Left" then
pos = Vector3.new(-4,0,0)
elseif surface.Name == "Right" then
pos = Vector3.new(4,0,0)
end
return pos
end
local num = 1
local blocks = RS.Blocks:GetChildren()
local Block_Choice = blocks[1]
numberOfBlocks = #blocks
script.Parent.Activated:Connect(function()
local target = mouse.Target
if target then
local surface = mouse.TargetSurface
local pos = part.Position--Surface(surface)
Event:FireServer(target,pos,Block_Choice)
end
end)
-- the selection part
mouse.Move:Connect(function()
if equipped == true then
local target = mouse.Target
local surface = mouse.TargetSurface
if target == game.Workspace.Map then
part.CanCollide = false
part.Parent = workspace
mouse.TargetFilter = part
local x = mouse.Hit.X
local y = mouse.Hit.Y
local z = mouse.Hit.Z
part.Position = Vector3.new(math.floor(x/4) * 4, math.floor(y/4) * 4 + 2, math.floor(z/4) * 4)
else
if target ~= game.Workspace.Map then
part.Position = Surface(surface)
end
end
end
end)
tool.Equipped:Connect(function()
equipped = true
part.Transparency = 0.5
end)
tool.Unequipped:Connect(function()
equipped = false
part.Transparency = 1
part.Position = Vector3.new(1,1,1)
end)
but it just don’t go up when i put my cursor above the block