Long time there were no updates. But I finally made some changes to the tool. First of all, I started freshly in a new place. Code is partially the same as before but I made few additions. First of all, I added a bound box, which detects if there are any other parts inside of it, and if there are any, it will not let the part be placed, and its holo will change color. Additionally I made it so that the parts are placed using the remote event and server script. The script grows in its size and I still face some issues while making this tool. The current script for what I have made is here:
local ContextActionService = game:GetService("ContextActionService")
local players = game.Players
local player = players.LocalPlayer
local tool = script.Parent
local boundBox = tool.BoundBox
local holo = tool.BlockHolo
local mouse = player:GetMouse()
local function Display(actionName, inputState, inputObject)
mouse.Move:Connect(function()
local worldSize = holo.CFrame:VectorToWorldSpace(holo.Size)
local absoluteSize = Vector3.new(math.round(math.abs(worldSize.X)), math.round(math.abs(worldSize.Y)), math.round(math.abs(worldSize.Z)))
local mousePosition = Vector3.new(math.round(mouse.Hit.Position.X), math.round(mouse.Hit.Position.Y), math.round(mouse.Hit.Position.Z))
local target = mouse.Target
local targetSurface = mouse.TargetSurface
local displayPos
local direction
if targetSurface == Enum.NormalId.Top then
direction = target.CFrame.UpVector
elseif targetSurface == Enum.NormalId.Bottom then
direction = -target.CFrame.UpVector
elseif targetSurface == Enum.NormalId.Front then
direction = target.CFrame.LookVector
elseif targetSurface == Enum.NormalId.Back then
direction = -target.CFrame.LookVector
elseif targetSurface == Enum.NormalId.Left then
direction = -target.CFrame.RightVector
elseif targetSurface == Enum.NormalId.Right then
direction = target.CFrame.RightVector
end
if direction == Vector3.new(1, 0, 0) then
displayPos = mousePosition + Vector3.new(direction.X * (absoluteSize.X / 2), 0, 0)
boundBox.Position = displayPos
elseif direction == Vector3.new(-1, 0, 0) then
displayPos = mousePosition + Vector3.new(direction.X * (absoluteSize.X / 2), 0, 0)
boundBox.Position = displayPos
elseif direction == Vector3.new(0, 1, 0) then
displayPos = mousePosition + Vector3.new(0, direction.Y * (absoluteSize.Y / 2), 0)
boundBox.Position = displayPos
elseif direction == Vector3.new(0, -1, 0) then
displayPos = mousePosition + Vector3.new(0, direction.Y * (absoluteSize.Y / 2), 0)
boundBox.Position = displayPos
elseif direction == Vector3.new(0, 0, 1) then
displayPos = mousePosition + Vector3.new(0, 0, direction.Z * (absoluteSize.Z / 2))
boundBox.Position = displayPos
elseif direction == Vector3.new(0, 0, -1) then
displayPos = mousePosition + Vector3.new(0, 0, direction.Z * (absoluteSize.Z / 2))
boundBox.Position = displayPos
end
local OverlapParams = OverlapParams.new()
OverlapParams.FilterDescendantsInstances = {tool}
OverlapParams.FilterType = Enum.RaycastFilterType.Exclude
local inBounds = workspace:GetPartBoundsInBox(boundBox.CFrame, boundBox.Size, OverlapParams)
if #inBounds == 0 then
holo.Color = Color3.fromRGB(0, 255, 0)
else
holo.Color = Color3.fromRGB(255, 0, 0)
end
holo.Position = displayPos
end)
end
local function RotateAndTilt(actionName, inputState, inputObject)
if inputObject.KeyCode == Enum.KeyCode.R and inputState == Enum.UserInputState.Begin then
boundBox.CFrame = boundBox.CFrame * CFrame.Angles(0, math.rad(90), 0)
local OverlapParams = OverlapParams.new()
OverlapParams.FilterDescendantsInstances = {tool}
OverlapParams.FilterType = Enum.RaycastFilterType.Exclude
local inBounds = workspace:GetPartBoundsInBox(boundBox.CFrame, boundBox.Size, OverlapParams)
if #inBounds > 0 then
holo.Color = Color3.fromRGB(255, 0, 0)
holo.CFrame = boundBox.CFrame
elseif #inBounds == 0 then
holo.Color = Color3.fromRGB(0, 255, 0)
holo.CFrame = boundBox.CFrame
end
elseif inputObject.KeyCode == Enum.KeyCode.T and inputState == Enum.UserInputState.Begin then
boundBox.CFrame = holo.CFrame * CFrame.Angles(0, 0, math.rad(90))
local OverlapParams = OverlapParams.new()
OverlapParams.FilterDescendantsInstances = {tool}
OverlapParams.FilterType = Enum.RaycastFilterType.Exclude
local inBounds = workspace:GetPartBoundsInBox(boundBox.CFrame, boundBox.Size, OverlapParams)
if #inBounds > 0 then
holo.Color = Color3.fromRGB(255, 0, 0)
holo.CFrame = boundBox.CFrame
elseif #inBounds == 0 then
holo.Color = Color3.fromRGB(0, 255, 0)
holo.CFrame = boundBox.CFrame
end
end
end
local function Place(actionName, inputState, inputObject)
if inputObject.UserInputType == Enum.UserInputType.MouseButton1 and inputState == Enum.UserInputState.Begin then
local inBounds = workspace:GetPartBoundsInBox(boundBox.CFrame, boundBox.Size)
if #inBounds == 0 then
local size = holo.Size
local cframe = holo.CFrame
local position = cframe.Position
local target = mouse.Target
game.ReplicatedStorage.PlacePart:FireServer(size, cframe, position, target)
else
print("Can't place part here!")
end
end
end
tool.Equipped:Connect(function()
ContextActionService:BindAction("RotateAndTilt", RotateAndTilt, false, Enum.KeyCode.R, Enum.KeyCode.T)
ContextActionService:BindAction("Display", Display, false, Enum.UserInputType.MouseButton1)
ContextActionService:BindAction("Place", Place, false, Enum.UserInputType.MouseButton1)
end)
tool.Unequipped:Connect(function()
ContextActionService:UnbindAction("RotateAndTilt")
ContextActionService:UnbindAction("Display")
ContextActionService:UnbindAction("Place")
end)
And this is server script activated with remote event:
game.ReplicatedStorage.PlacePart.OnServerEvent:Connect(function(player, size, cframe, position, target)
local part = Instance.new("Part")
part.Size = size
part.CFrame = cframe
part.Parent = workspace
part.Position = position
local weld = Instance.new("WeldConstraint")
weld.Part0 = part
weld.Part1 = target
weld.Parent = part
end)
And here is a little showcase of how it looks right now:
But as I said, issues are still present. For example, the functions that detects mouse movement seems to work even after the tool is unequipped, and the holo of a part stays in place on server side, which looks a little strange.
If anybody has any ideas how would I optimize my script, please tell me, it would be really appreciated.