Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Can Anyone Fix My CFrame Loop Problem?

Asked by 10 years ago

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)
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. jobro13 980 — 10y
0
Try "until (Door1.Position - Vector3.new(94.2,18.2,79.3)).magnitude < 0.05" jobro13 980 — 10y

1 answer

Log in to vote
0
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
10 years ago

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.

Ad

Answer this question