I want to know how to make an encounter system where if you are walking in grass for like a random amount of time between 3 to 7 seconds, you find an encounter. If you stop walking or leave the grass, it resets the timer. This is part of my code. It only works once and if u stop in the grass you still get an encounter:
local parts = script.Parent:GetChildren()
local debounce = false
for _, part in pairs(parts) do
if part:IsA("Part") then
part.Touched:Connect(function(hit)
if debounce == false then
debounce = true
if hit.Parent:FindFirstChild("Humanoid") then
local iteration = 1
while wait(0.05) do
local touching = false
if hit.Parent.Humanoid.MoveDirection.Magnitude == 0 then
debounce = false
end
for i,v in part:GetTouchingParts() do
if v.Parent == hit.Parent then
touching = true
end
end
if touching == false then
debounce = false
end
coroutine.wrap(function()
if iteration == 1 then
local randTime = math.random(3,7)
wait(randTime)
hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 0
local encounter = chooseRandom(part:GetAttribute("locationNum"))
event:FireClient(game.Players:GetPlayerFromCharacter(hit.Parent),encounter)
event.OnServerEvent:Connect(function(plr)
hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 16
debounce = false
end)
end
end)()
iteration += 1
if debounce == false then
break
end
end
end
end
end)
end
end
A reason why you can only encounter an enemy once is the fact your script only executes once. The for loop that cycles through your variable, parts will only fire once since you don’t have anyway of looping it or executing it again. All the code nested within the loop will not run as a result.
A solution could be putting all the code (besides the variables) inside a function and have a touched event that will fire this function to check if the player is touching a part within the part variable.
Nevermind, I think it was something else in a local script. a debounce I forgot to set to false. I just need ideas on why when I stop moving it encounters and for some reason I need to exit the grass to get another encounter
I redid the script a little and I used print debugging, I made a timer that counts down when you move in the grass and once it reaches below 0 it fires the encounter. I still need to test this a bit because I’ve had some bugs like when exiting the battle it immediately fires another one or it starts 2 timers at the same time. A lot of while loops is not that efficient but it kinda works. I added an invisible part over the grass that makes it much easier to detect if there is a humanoid there. Here’s the code:
local function GetTouchingParts(part)
local connection = part.Touched:Connect(function() end)
local results = part:GetTouchingParts()
connection:Disconnect()
return results
end
local debounce = false
local function encounter(hit,part)
local randTime = math.random(3,7)
while wait(0.1) do
local touching = false
for i,v in pairs(workspace:GetPartsInPart(part.InvisiblePart)) do
if v.Parent == hit.Parent then
touching = true
end
end
if touching == true and hit.Parent.Humanoid.MoveDirection.Magnitude > 0 then
randTime -= 0.1
print(randTime)
end
if randTime < 0 then
hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 0
local chosen = chooseRandom(part:GetAttribute("locationNum"))
event:FireClient(game.Players:GetPlayerFromCharacter(hit.Parent),chosen)
event.OnServerEvent:Connect(function(plr)
randTime = math.random(3,7)
hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 16
debounce = false
end)
end
end
end
local parts = script.Parent:GetChildren()
for _, part in pairs(parts) do
if part:IsA("Part") then
while wait(0.99) do
coroutine.wrap(function()
for i,v in pairs(GetTouchingParts(part.InvisiblePart)) do
if v.Parent:FindFirstChild("Humanoid") then
if debounce == false then
debounce = true
encounter(v,part)
end
end
end
end)()
end
end
end
I figured it out! I just had to remove the coroutine in the while loop that checks if a part in the parts folder is being touched, and add a wait before making the debounce false so that you can ensure the timer gets reset. Here is the new code:
local function GetTouchingParts(part)
local connection = part.Touched:Connect(function() end)
local results = part:GetTouchingParts()
connection:Disconnect()
return results
end
local debounce = false
local function encounter(hit,part)
local randTime = math.random(3,7)
while wait(0.1) do
local touching = false
for i,v in pairs(workspace:GetPartsInPart(part.InvisiblePart)) do
if v.Parent == hit.Parent then
touching = true
end
end
if touching == true and hit.Parent.Humanoid.MoveDirection.Magnitude > 0 then
randTime -= 0.1
print(randTime)
end
if randTime < 0 then
hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 0
local chosen = chooseRandom(part:GetAttribute("locationNum"))
event:FireClient(game.Players:GetPlayerFromCharacter(hit.Parent),chosen)
event.OnServerEvent:Connect(function(plr)
randTime = math.random(3,7)
hit.Parent:FindFirstChild("Humanoid").WalkSpeed = 16
wait()
debounce = false
end)
end
end
end
local parts = script.Parent:GetChildren()
for _, part in pairs(parts) do
if part:IsA("Part") then
while wait(0.99) do
for i,v in pairs(GetTouchingParts(part.InvisiblePart)) do
if v.Parent:FindFirstChild("Humanoid") then
if debounce == false then
debounce = true
encounter(v,part)
end
end
end
end
end
end