Tab your code correctly. Also, use good variable names. I could more easily suggest how to clean up your code, but first I have to figure out what r, x, e, or d are supposed to mean.
I'm not sure you'll remember in two months, either.
while loops try again the moment their body finishes. If you don't use wait(), working on this loop this will consume all of ROBLOX's time and lead to a crash.
Your while loop starting line 11 does not always wait(). It wait()s in two conditions:
This leaves open the range where x is between 30 and 50.
When you have a loop like this, it's good hygiene to do the wait() at the very beginning or end of the loop, to avoid this problem, and to avoid repeating wait() all over the place.
Cleanup
I see a lot of ways to clean this up.
First, name your variables better. d seems to be used in a debounce pattern. canOpen is a much more descriptive name for it.
plr is a silly way to write player. This is not the 70's, you don't need to save a few bytes. Writing out the English word means you save the time of deciphering and remembering which shortening you used (playr, plyr, plr, player?). Save your time by just using the proper spelling.
When you find yourself repeating yourself so much you need to shorten words, that's usually the sign that something else is wrong.
e is not used.
You have a variable door2, but later use script.Parent.Union. Use your variables!
Using == true on a boolean, or ~= nil on anything else is redundant.
All of the logic in the if r >= 30 then statement should be moved after the while true do loop. It saves indentation and makes the flow of your code clearer.
if player and player.Character:FindFirstChild("KeyName") and canOpen then
canOpen = false
while true do
wait(.06)
if x < 30 then
door2.CFrame = door2.CFrame + (door2.CFrame.lookVector * 1)
x = x + 1
elseif x >= 50 then
door2.CFrame = door2.CFrame - (door2.CFrame.lookVector * 1)
r = r + 1
if r >= 30 then
break
end
end
end
r = 0
canOpen = true
x = 0
end
Notice how you know have something that looks like
while true do
if stopcondition then
break
end
end
Since we know that that stopcondition can never be true at the beginning of the loop, that means you should probably just write this as
while not stopcondition do
end
Cleaned up
All in all, you get
x = 0
canOpen = true
r = 0
door2 = script.Parent.Union
function Touch(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player and player.Character:FindFirstChild("KeyName") and canOpen then
canOpen = false
while r < 30 do
wait(.06)
if x < 30 then
door2.CFrame = door2.CFrame + (door2.CFrame.lookVector * 1)
x = x + 1
elseif x >= 50 then
door2.CFrame = door2.CFrame - (door2.CFrame.lookVector * 1)
r = r + 1
end
end
r = 0
x = 0
canOpen = true
end
end
door2.Touched:connect(Touch)
This code doesn't quite add up to me.
You only increase x by 1 while it's less than 30. That means x >= 50 is never going to happen.
2 comments
As far as I can tell, this should not cause studio to crash. Try disabling the script. If studio still crashes then something else is causing it.
It becomes an infinite loop so it does.