Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Can Anyone Fix My CFrame Loop Problem?

Hey guys, my script is supposed to subtract the position until it gets to a certain position. It's all working fine, except the door does not stop at the exact point I want it to. Can anyone see what I did wrong?

Sensor1 = script.Parent.Sensors.Sensor1
Sensor2 = script.Parent.Sensors.Sensor2
Door1 = script.Parent.Doors.Door1
Door2 = script.Parent.Doors.Door2
debounce = false

function OpenDoor()
	repeat
		Door1.CFrame = Door1.CFrame - Vector3.new(0, 0, .1)
		wait(.01)
	until Door1.Position == Vector3.new(94.2, 18.2, 79.3)
end

Sensor2.Touched:connect(function (hit)
	if not hit.Parent:FindFirstChild("Humanoid") then return end
	if not debounce then
		debounce = true
		OpenDoor()
		debounce = false
	end
end)

2 comments

0

My guess is that there is a floating point error (basically a binary math error, same reason as we can't write (1/3) down as a number - binary has problems with 0.1 if I'm right!). This means that it will never get exactly that position.

0

Try "until (Door1.Position - Vector3.new(94.2,18.2,79.3)).magnitude < 0.05"

1 answer

✓ Accepted answer

Generally, you shouldn't compare the equality of Vector3's. This is because Vector3 values are represented as not very accurate floating point numbers, and so the values may not be represented in quite the right way.

It's also unfortunate that you're referencing a specific position in the world in your script; this makes this solution really brittle if you ever want to move the door; make another one using this; etc.

Also, repeat .. until loops tend to be messy; I used to use them a lot but they usually are not the best solution. For instance, in this case, if the door was already at that position, starting the loop would make it go past and then never stop.

So, modifying what you have, this is what you should do:

while Door1.CFrame.p.y > 18.2 do
	Door1.CFrame = Door1.CFrame + Vector3.new(0,-0.1,0);
	wait(0.03);
	-- Note that most of the time,
	--0.03 is the minimum time that can be waited
end

However, I would recommend instead organizing it like this:


-- Two extra varaibles:
local doorHeight = 20;
-- Or whatever; the amount that the
-- door moves before stopping
local start = Door1.CFrame;

...

-- Now our loop:

for dy = 0,-doorHeight, -0.3 do
	Door1.CFrame = start + Vector3.new(0,dy,0);
	wait(0.03);
end

Advantage of the second one is that the math is not relative to the current state. This in general can make things a lot easier to reason about.


Both solutions work, one you may find more elegant than the other. Hopefully this is helpful.

This discussion is preserved as it was. New answers, comments, and votes are closed.