Currently working on my placement system, and each model has a PrimaryPart (a Hitbox)
Point of the Hitbox is for when placing furniture, so furniture can’t intersect. I have a separate system checking for collision of hitboxes for furniture, however, I am working on walls. Now walls also have a Hitbox, as that Hitbox is what’s used for the movement and players can intersect walls, however, you can currently spam click on the same spot and place the same wall on top of each other. The chances of this becoming a massive issue in my game is unlikely (as it costs money to place walls down, so no point in placing 100 walls in the same spot) but I still want to stop this from happening in case somebody accidentally double clicks.
So in short, is there a way to check for models PrimaryPart having the same position as an already placed item? I know I could probs do something like
if placingModel.PrimaryPart.Position == model.PrimaryPart.Position then print('Can't place') end
put if there are hundreds of models.
Tried using something like this:
click = mouse.Button1Down:connect(function()
for _, allModels in pairs(playersPlot.Purchases:GetChildren()) do
if wallClone.PrimaryPart.Position ~= allModels.PrimaryPart.Position then
click:Disconnect()
renderStepped:Disconnect()
place:FireServer(wallClone.Name, wallClone.PrimaryPart.CFrame)
wallClone:Destroy()
self:StartPlacing(playersPlot, mouse, wallType)
end
end
end)
But that ended up firing the place event 30-40 times
Comparing vectors like this probably doesn’t work all the time because of floating point errors. If you are checking whether two positions are really close / the same as each other, check if the distance between the two is below a certain small value, like 0.0001:
local sigma = 0.0001
(...)
if (wallClone.PrimaryPart.Position - allModels.PrimaryPart.Position).magnitude > sigma then
Other than that, I think you can use GetTouchingParts here on the hitbox to pre-filter workspace on just the parts that are touching that hitbox, then you can only use that list rather than looping over the entire model list.
Don’t think GetTouchingParts would work, as the part you are placing has CanCollide set to false. This is so your character doesnt get in the way of the part being placed
But touching parts would still be fired if the are touching, but not in the exact same position? I need it to check if the parts are in the exact same position, orientation, CFrame, whatever
Yeah I checked the link, but this would fire if the parts are touching. I’m not after if the parts are touching, I need if they are in the exact same spot.
I understand that. Please read my earlier post. It allows you to get a filtered list of things to check for, so that you don’t need to loop over every model you have in workspace / wherever and compare it to each one, but rather only a subset that is already touching the part (then you do your extra checks on top of that). You wouldn’t just use the result of GetTouchingParts raw.
for _, allModels in pairs(playersPlot.Purchases:GetChildren()) do
if (wallClone.PrimaryPart.Position - allModels.PrimaryPart.Position).magnitude > 0.0001 then
click:Disconnect()
renderStepped:Disconnect()
place:FireServer(wallClone.Name, wallClone.PrimaryPart.CFrame)
wallClone:Destroy()
self:StartPlacing(playersPlot, mouse, wallType)
break
end
end
The break stops the placing of multiple models at once, but you can still place parts on top of each other
Right, I see what you are trying to do now. You’ll want to do all your checks first and jump out of the function once you find something that blocks the place. So the code would be:
click = mouse.Button1Down:connect(function()
for _, allModels in pairs(playersPlot.Purchases:GetChildren()) do
if (wallClone.PrimaryPart.Position - allModels.PrimaryPart.Position).magnitude < 0.0001 then
return -- blocked
end
end
-- not blocked
end)
Rip, I really thought this would have worked, but now it doesn’t place at all
local click
click = mouse.Button1Down:connect(function()
print('Click')
for _, allModels in pairs(playersPlot.Purchases:GetChildren()) do
if (wallClone.PrimaryPart.Position - allModels.PrimaryPart.Position).magnitude > 0.0001 then
print('Model found with same position!')
return
end
end
print('Place model')
click:Disconnect()
renderStepped:Disconnect()
place:FireServer(wallClone.Name, wallClone.PrimaryPart.CFrame)
wallClone:Destroy()
self:StartPlacing(playersPlot, mouse, wallType)
end)
Prints Click and Model found with same position! even with no models even close to the placing model
You gotta flip the condition on the if-statement, so < .0001 instead. Currently you have > .0001 will go through for the first part that isn’t in the position, you want it to fall through when the part is in the position instead.