I want to achieve this in my building system and how to do this like the block is not going outside?
do i need math here and modify the code?
Code:
-- // SERVICES \\ --
local Players = game:GetService("Players")
local repStorage = game:GetService("ReplicatedStorage")
local UIS = game:GetService("UserInputService")
local CAS = game:GetService("ContextActionService")
local runService = game:GetService("RunService")
local workspace = game.Workspace
-- // FOLDERS \\ --
local Events = repStorage:WaitForChild("Events")
local Models = repStorage:WaitForChild("Models")
-- // WORKSPACE FOLDERS
local IgnoredBlocks = workspace.Base:WaitForChild("IgnoredBlocks")
local PlacedBlocks = workspace.Base:WaitForChild("PlacedBlocks")
-- // EVENTS \\ --
local PlaceBlock = Events:WaitForChild("PlaceBlock")
local RemoveBlock = Events:WaitForChild("RemoveBlock")
local GetSelectedBlock = Events:WaitForChild("GetSelectedBlock")
-- // VARIABLES \\ --
local SelectionBox = repStorage:WaitForChild("RemoveBox")
local ignoreList = {IgnoredBlocks}
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local target
local pos
local norm
local isEnabled = false
local canPlace = false
local rotation = 0
local selectedBlock
local modeldata = nil
local selectedpos = 1
local mode = "build"
local MAX_PLACEMENT_DISTANCE = 360
local RemoveBox = RemoveBlock:Clone()
local fakeBlock
-- // MAIN \\ --
Mouse.TargetFilter = IgnoredBlocks
Mouse.Icon = "rbxasset://textures/ArrowCursor.png"
function doFakeMouseStuff()
local mouseRay = Mouse.UnitRay
local newRay = Ray.new(mouseRay.Origin, mouseRay.Direction.unit * MAX_PLACEMENT_DISTANCE)
target, pos, norm = workspace:FindPartOnRayWithIgnoreList(newRay, ignoreList)
end
function getblockPos(vec, block)
local posx = math.floor(vec.X / block.PrimaryPart.Size.X + .5) * block.PrimaryPart.Size.X
local posy = math.floor(vec.Y / block.PrimaryPart.Size.Y + .5) * block.PrimaryPart.Size.Y
local posz = math.floor(vec.Z / block.PrimaryPart.Size.Z + .5) * block.PrimaryPart.Size.Z
return Vector3.new(posx, posy, posz)
end
function placeBlock(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
if isEnabled == true then
if mode == "build" and canPlace == true then -- if the mode is build mode
PlaceBlock:FireServer(selectedBlock, fakeBlock.PrimaryPart.CFrame) -- fires the event to place a block
elseif mode == "remove" then -- if the mode is remove mode
if Mouse.Target ~= workspace and Mouse.Target ~= "Base" and Mouse.Target ~= nil then -- detects if the Target is nil
if Mouse.Target.Parent:IsA("Model") then -- detects if the Target instance is a Model
RemoveBlock:FireServer(Mouse.Target.Parent) -- fires the event and remove the block
end
end
end
end
end
end
function enablePlacing(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
if isEnabled == true then
isEnabled = false
Mouse.Icon = "rbxasset://textures/ArrowCursor.png"
else
isEnabled = true
if mode == "build" then
Mouse.Icon = "rbxassetid://66887745"
else
Mouse.Icon = "rbxassetid://72539748"
end
end
end
end
function changeMode(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
if isEnabled == true then
if mode == "build" then
mode = "remove"
Mouse.Icon = "rbxassetid://72539748"
else
mode = "build"
Mouse.Icon = "rbxassetid://66887745"
end
end
end
end
function openBlockMenu(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
if isEnabled == true and mode == "build" and modeldata ~= nil then
selectedBlock = Models:WaitForChild(modeldata[selectedpos].Name)
fakeBlock:Destroy()
fakeBlock = selectedBlock:Clone()
if selectedpos == #modeldata then
selectedpos = 1
else
selectedpos = selectedpos + 1
end
end
end
end
function rotateBlock(actionName, inputState, inputObj)
if inputState == Enum.UserInputState.Begin then
if fakeBlock.Parent ~= nil then -- detects if the hoverblock is nil
fakeBlock:SetPrimaryPartCFrame(fakeBlock.PrimaryPart.CFrame * CFrame.Angles(math.rad(fakeBlock.PrimaryPart.Orientation.X), math.rad(rotation + 90), math.rad(fakeBlock.PrimaryPart.Orientation.Z))) -- rotates the block
end
end
end
CAS:BindAction("changeMode", changeMode, false, Enum.KeyCode.X)
CAS:BindAction("rotateBlock", rotateBlock, false, Enum.KeyCode.R)
CAS:BindAction("enablePlacing", enablePlacing, false, Enum.KeyCode.E)
CAS:BindAction("openBlockMenu", openBlockMenu, false, Enum.KeyCode.Q)
CAS:BindAction("placeBlock", placeBlock, false, Enum.UserInputType.MouseButton1)
GetSelectedBlock.Event:Connect(function(block)
if fakeBlock ~= nil then
fakeBlock:Destroy()
end
selectedBlock = Models:WaitForChild(block)
fakeBlock = selectedBlock:Clone()
end)
GetSelectedBlock:Fire("Block")
modeldata = {}
for i, v in pairs(Models:GetChildren()) do
table.insert(modeldata, v)
end
runService.RenderStepped:Connect(function()
for i, plr in pairs(Players:GetPlayers()) do
table.insert(ignoreList, plr.Character)
end
doFakeMouseStuff()
if isEnabled == true then
if fakeBlock.Parent == nil then
fakeBlock = selectedBlock:Clone()
fakeBlock.Parent = IgnoredBlocks
end
if mode == "build" then
RemoveBox:Destroy()
if fakeBlock.Parent == nil then
fakeBlock = selectedBlock:Clone()
fakeBlock.Parent = IgnoredBlocks
end
if fakeBlock and pos and norm then
for i,v in pairs(fakeBlock:GetChildren()) do
v.CanCollide = false
v.Transparency = .6
if i > 1 then
fakeBlock.PrimaryPart.Transparency = 1
end
if Mouse.Target ~= nil then
v.Color = Color3.fromRGB(9, 137, 207)
canPlace = true
else
v.Color = Color3.fromRGB(170, 0, 0)
canPlace = false
end
end
doFakeMouseStuff()
local endPos = getblockPos(
pos + (
norm * (fakeBlock.PrimaryPart.Size * .25)
),
fakeBlock
)
fakeBlock:SetPrimaryPartCFrame(
CFrame.new(endPos) * CFrame.Angles(
math.rad(fakeBlock.PrimaryPart.Orientation.X),
math.rad(fakeBlock.PrimaryPart.Orientation.Y),
math.rad(fakeBlock.PrimaryPart.Orientation.Z)
)
)
end
elseif mode == "remove" then
fakeBlock:Destroy()
if RemoveBox.Parent == nil then
RemoveBox = SelectionBox:Clone()
RemoveBox.Parent = IgnoredBlocks
end
if Mouse.Target ~= game.Workspace.Base and Mouse.Target ~= nil then
if Mouse.Target.Parent:IsA("Model") and Mouse.Target.Parent.PrimaryPart ~= nil and Mouse.Target.Parent:FindFirstChild("Placer") then
local bbOrientation, bbSize = Mouse.Target.Parent:GetBoundingBox()
RemoveBox:SetPrimaryPartCFrame(Mouse.Target.Parent.PrimaryPart.CFrame)
RemoveBox.PrimaryPart.Size = Vector3.new(bbSize.X + .001, bbSize.Y + .001, bbSize.Z + .001)
else
RemoveBox:Destroy()
end
else
RemoveBox:Destroy()
end
end
else
if selectedBlock ~= nil then
fakeBlock:Destroy()
RemoveBox:Destroy()
end
end
if fakeBlock.Parent ~= nil or RemoveBox.Parent ~= nil then
if Player.Character.Humanoid.Health < 1 then
game:GetService("Debris"):AddItem(fakeBlock and RemoveBox, 0)
isEnabled = false
end
end
end)