Hey, I am trying to make a press “F” to sit type of script and but I am having a small issue where I couldn’t detect all the seats inside a folder. How can I improve my scripts to make them work?
for i, v in pairs(workspace.SeatFolder:GetChildren())do
while wait()do
if v and (player.Character.PrimaryPart.Position - v.Position).Magnitude < distance then
tween:Play()
Button.Button.Text = “F - Sit”
Button.Adornee = v
else
tween2:Play()
wait(.5)
Button.Button.Text = “”
Button.Adornee = nil
end
end
end
for i, v in pairs(workspace.SeatFolder:GetChildren())do
coroutine.resume(coroutine.create(function()
while wait()do
if v and (player.Character.PrimaryPart.Position - v.Position).Magnitude < distance then
tween:Play()
Button.Button.Text = "F - Sit"
Button.Adornee = v
else
tween2:Play()
wait(.5)
Button.Button.Text = ""
Button.Adornee = nil
end
end
end))
end
You need to add the while loop into a coroutine because the while loop will only allow one seat to be detected and won’t let the for loop to go to the other seats
If you want an explanation to @Tommybridge’s solution:
What he added was a coroutine, which basically ran in a different thread than the main script.
Think of it like “multiple scripts in one script”, so he’s running the while loop in different threads so it will not yield the entire script, only the new thread.
Spawn() is also an alternative option if you don’t feel like typing out that entire line. Does the same exact thing in this particular context. Coroutines could be the better option in a different scenario.
This topic explains the difference really well if you want to read through it.
You’re calling Tween:Play() every time the while loop passes.
What I’d do is make two variables: ‘State’, and ‘PreviousState’ which would just be either 1 or 2.
State ‘1’ means it’s found a seat, where ‘2’ means it hasn’t.
Then before you call Tween:Play(), check if the current State is NOT equal to PreviousState, this will indicate a state change and you can set PreviousState to the current one.
EDIT: There’s a wait .5 thingy, forgot to do that…
local State,PreviousState = 0,0
local Callbacks = {
[1] = function() -- State 1
Button.Button.Text = "F - Sit"
Button.Adornee = v
end;
[2] = function()
Button.Button.Text = ""
Button.Adornee = nil
end;
}
for i, v in pairs(workspace.SeatFolder:GetChildren())do
spawn(function()
while wait() do
local WaitTime = 0;
if v and (player.Character.PrimaryPart.Position - v.Position).Magnitude < distance then
State = 1
else
State = 2
WaitTime = .5
end
local TweenToPlay = State == 1 and tween or State == 2 and tween2
if (PreviousState ~= State) then
TweenToPlay:Play()
wait(WaitTime)
(Callbacks[State])()
end
PreviousState = State
end
end)
end
for i, v in pairs(workspace.SeatFolder:GetChildren())do
coroutine.resume(coroutine.create(function()
while wait()do
if v and (player.Character.PrimaryPart.Position - v.Position).Magnitude < distance then
if tween.PlaybackState ~= Enum.PlaybackState.Playing then
tween:Play()
Button.Button.Text = "F - Sit"
Button.Adornee = v
end
else
if tween2.PlaybackState ~= Enum.PlaybackState.Playing then
tween2:Play()
wait(.5)
Button.Button.Text = ""
Button.Adornee = nil
end
end
end
end))
end
Edit: This won’t work, it will just loop the tween.
Yeah that’s exactly the problem. That’s why it’s probably best to (assuming we don’t wanna change the fact that it runs in a while loop) just compare the tween we want to play to the tween that was played last.
local State,PreviousState = 0,0
local Callbacks = {
[1] = function(seat) -- State 1
Button.Button.Text = "F - Sit"
Button.Adornee = seat
end;
[2] = function(seat)
Button.Button.Text = ""
Button.Adornee = nil
end;
}
for i, v in pairs(workspace.SeatFolder:GetChildren())do
spawn(function()
while wait() do
local WaitTime = 0;
if v and (player.Character.PrimaryPart.Position - v.Position).Magnitude < distance then
State = 1
else
State = 2
WaitTime = .5
end
local TweenToPlay = State == 1 and tween or State == 2 and tween2
if (PreviousState ~= State) then
TweenToPlay:Play()
wait(WaitTime)
local Function = Callbacks[State] or function()end
Function(v)
end
PreviousState = State
end
end)
end