I’m making a building system and I did a code to make the object unplacable if it is outside of the part called “Area”, the code currently detect if a piece of the object is inside the area. This is the code:
local function insideArea()
local plr = game.Players.LocalPlayer
local buildArea = "ConstructionArea"..plr.Area.Value
local max = 0
local previewObject = workspace.PreviewObject
local blockTable = {
workspace.PreviewObject;
}
local params = OverlapParams.new()
params.CollisionGroup = "Default"
params.FilterDescendantsInstances = blockTable
params.FilterType = Enum.RaycastFilterType.Whitelist
params.MaxParts = max
local area = workspace.Areas[buildArea].Base.Area
local count = 0
for i,v in pairs (previewObject:GetDescendants()) do
if v:IsA("BasePart") then
count = count + 1
end
end
if count ~= 0 then
local resultTable = workspace:GetPartBoundsInBox(area.CFrame,area.Size,params)
if #resultTable >= count then
return true
else
return false
end
end
end
The blue is the “Area” part, the part that the object has to be touching to can be placed. How I mentioned above, I want that the entire object need to touch, and not just a piece.
Create 2 points with something that can be touched (maybe a part, or something else if you don’t like using parts for that kind of thing), one at the top left of the model and one at the bottom right. Require both of them to be inside of the area for the model to be placeable.
I’ll let you figure out how to do it as it’s probably better for you to do it how you want it and to play around with it so it works for you.
You could calculate the 8 corners of the bounding box of the couch.
Then check if each of the corners x,y,z position values are within your designated area’s 8 corners.
Assuming all of these are cuboids and not other kinds of shapes.
It worked, but I’m looking for script solutions, cuz I don’t wanna have to create two parts in each object. If there’s no other way I’m gonna use that.
I think that might be possible make a script detecting the top left and bottom right of a part (the hitbox part that i put on every object)
Use the function in the first post of this. And check if each of your corners (Pos in the function) are within the two corners of your designated area (A, B)
I used iNazgxl’s solution, but I made it a script, with the help of this post
Here’s the new script for who wants:
function getCorners(part) --by post
local cf = part.CFrame
local size = part.Size
local corners = {}
local frontFaceCenter = (cf + cf.LookVector * size.Z/2)
local backFaceCenter = (cf - cf.LookVector * size.Z/2)
local topFrontEdgeCenter = frontFaceCenter + frontFaceCenter.UpVector * size.Y/2
local bottomFrontEdgeCenter = frontFaceCenter - frontFaceCenter.UpVector * size.Y/2
local topBackEdgeCenter = backFaceCenter + backFaceCenter.UpVector * size.Y/2
local bottomBackEdgeCenter = backFaceCenter - backFaceCenter.UpVector * size.Y/2
corners.topFrontRight = (topFrontEdgeCenter + topFrontEdgeCenter.RightVector * size.X/2).Position
corners.topFrontLeft = (topFrontEdgeCenter - topFrontEdgeCenter.RightVector * size.X/2).Position
corners.bottomFrontRight = (bottomFrontEdgeCenter + bottomFrontEdgeCenter.RightVector * size.X/2).Position
corners.bottomFrontLeft = (bottomFrontEdgeCenter - bottomFrontEdgeCenter.RightVector * size.X/2).Position
corners.topBackRight = (topBackEdgeCenter + topBackEdgeCenter.RightVector * size.X/2).Position
corners.topBackLeft = (topBackEdgeCenter - topBackEdgeCenter.RightVector * size.X/2).Position
corners.bottomBackRight = (bottomBackEdgeCenter + bottomBackEdgeCenter.RightVector * size.X/2).Position
corners.bottomBackLeft = (bottomBackEdgeCenter - bottomBackEdgeCenter.RightVector * size.X/2).Position
return corners
end
local function checkArea()
local plr = game.Players.LocalPlayer
local buildArea = "ConstructionArea"..plr.Area.Value
local max = 0
local previewObject = workspace.PreviewObject
local blockTable = {}
for cornerName, cornerPos in pairs(getCorners(previewObject.Hitbox)) do
if not previewObject.Hitbox.Corners:FindFirstChild(cornerName) then
local part = Instance.new("Part") -- create the part in the corner position of my model's hitbox
part.Name = cornerName
part.Position = cornerPos
part.Anchored = true
part.Transparency = 1
part.Size = Vector3.new(0.1,0.1,0.1)
part.Parent = previewObject.Hitbox.Corners
table.insert(blockTable,part)
elseif previewObject.Hitbox.Corners:FindFirstChild(cornerName) then
blockTable[previewObject.Hitbox.Corners[cornerName]] = nil
previewObject.Hitbox.Corners[cornerName]:Destroy()
local part = Instance.new("Part") --re-create the block each 0.1 seconds
part.Name = cornerName
part.Position = cornerPos
part.Anchored = true
part.Transparency = 1
part.Size = Vector3.new(0.1,0.1,0.1)
part.Parent = previewObject.Hitbox.Corners
table.insert(blockTable,part)
end
end
local params = OverlapParams.new()
params.CollisionGroup = "Default"
params.FilterDescendantsInstances = blockTable
params.FilterType = Enum.RaycastFilterType.Whitelist
params.MaxParts = max
if workspace.Areas:FindFirstChild(buildArea) then
local area = workspace.Areas[buildArea].Base.Area
local count = #blockTable
if count ~= 0 then
local resultTable = workspace:GetPartBoundsInBox(area.CFrame,area.Size,params)
if #resultTable >= count then
return true
else
return false
end
end
end
end
while true do
wait(0.1)
local hitbox = workspace.PreviewObject.Hitbox -- hitbox
checkArea(hitbox)
-- rest of the code (change color)
end
this solution should work for objects of any shape, not just orthogonal ones
take your container, create a bigger one overlapping it completely
do a negation of those two, you will get a new container volume which lacks the volume of the first one
fast version
check for GetPartBoundsInBox(myPart:GetPivot(), myPart:GetSize(), olap); if result contains container2, that highly likely means your part touches the bigger container, although false positive is possible especially for tilted and concave objects
precise version (requires physical simulation)
clone and move all mentioned parts and containers behind the borders of your playing area
set Anchored to false and subscribe for Touched event; if container2 immediately reports touching your part, that is a positive; otherwise, cancel the simulation and destroy all cloned parts