How to check for a parts position?

I created a script that checks to see if my pizza box is in a certain spot or if it even exists. If it doesn’t exist or if it isn’t in that specific spot, it will spot a new one when they click a button. However, with the code below, it keeps cloning and creating new boxes and I’m not sure what I did wrong with the part that checks if it is at the specific location or not. If anyone knows the issue that would be great!

local clickDetector = script.Parent.ClickDetector
local gui = script.Parent.SurfaceGui.TextBox


function onMouseClick(player)
	if game.Workspace["Pizza Box"].Position ~= Vector3.new(-30.24, 2.35, -100.4) or game.Workspace["Pizza Box"] == nil then
		local newBox = game.ReplicatedStorage["Pizza Box"]:Clone()
		newBox.Parent = workspace
		newBox.CFrame = CFrame.new(-30.24, 2.35, -100.4)
	else
		print("Pizza Box Not Spawned")
	end
end

clickDetector.MouseClick:Connect(onMouseClick)

Yes it is (30 Characterssssss)

You may be running into a problem with CFrame and Vector3. Typically, it’s not a good idea to try to compare position vectors due to possible floating point error. I would suggest instead for you to make a “deadband” to see if your Pizza Box is within a given area. You could use Region3s for this. Another easier solution would be to just keep track of your spawned pizza boxes in a table instead.

Can you explain what a deadband is? Do I just create an invisible block and see if it is touching it?

Was just about to say what @Kyles45678 said about comparing positions.

Also, I would change the logic around to check if the box exists first. You can use FindFirstChild for that:

local box = workspace:FindFirstChild("Pizza Box")
if (box ~= nil and box.Position ~= ...) then

If ‘box’ evaluates to nil, the first part of the if statement will exit and it will not bother checking the position since the part doesn’t exist.

1 Like

An invisible block would work. A deadband is a common programming technique where you check if your value is within a given range of values. A deadband has a maximum value and a minimum value. For example, if I have a value, lets say voltage, I want to only get the voltage values inbetween 5 volts and 12 volts. So, I could write a function that returns any voltage between those 2 values.

local function getVoltage(volts)
    if volts > 5 and volts < 12 then return volts end
end

That’s just a simply example, but there’s a way you can do with with vectors too. I think it would be easier for you to do the invisible part touching though.

1 Like

Oh I’ve done this with the rest of my code, I just got lazy thanks for mentioning it though!

For Vector3’s, you’d need to check if each component of the position is inside their required range.

local function isVectorCloseTo(var, const, threshold)
	local upper = const + (Vector3.new(1, 1, 1) * threshold)
	local lower = const - (Vector3.new(1, 1, 1) * threshold)
	return ((var.X >= lower.X and var.X <= upper.X) and
		(var.Y >= lower.Y and var.Y <= upper.Y) and
		(var.Z >= lower.Z and var.Z <= upper.Z))
end

local position = Vector3.new(1.126, 1.326, 1.489)
local spawnpoint = Vector3.new(1, 1, 1)
print(isVectorCloseTo(position, spawnpoint, 0.5)) -- true

This function would check if a point var is inside an imaginary cube of size threshold * 2 centered around point const

1 Like

Another realization, you can also just subtract the vectors and take the Magnitude of their difference to find the distance between them.

I’ve been dumb today.