Hi everyone i’m doing a client-sided cube spawning & collecting system with collect radius
when playing the game everything works fine but then at one moment cubes become unable to collect but keep spawning (up to limit) and i don’t understand why
everything around cubes CanTouch set to false (when they unable to collect they still have touchinterest instance in them)
i’ll appreciate help with fixing this bug and any tips about improving the system
the code:
functions
local function AnimateCollect(cube: Part)
TS:Create(cube, cubeInfo, {Transparency = 1}):Play()
TS:Create(cube, cubeInfo, {Position = cube.Position + Vector3.new(0, 3, 0)}):Play()
task.spawn(function()
wait(0.5)
cube:Destroy()
end)
end
local takedPositions = {}
local debounce = true
local function SpawnCube()
if #CubesFolder:GetChildren() >= 100 then return end
local randomX = math.random(-spawnArea.Size.X/2 + 0.5, spawnArea.Size.X/2 - 0.5)
local randomZ = math.random(-spawnArea.Size.Z/2 + 0.5, spawnArea.Size.Z/2 - 0.5)
local ChoosedCube = CubesModule.ChooseCube()
local Cube = CubesModels:WaitForChild(ChoosedCube):Clone()
Cube.Touched:Once(function(touch)
if Players:GetPlayerFromCharacter(touch.Parent) == player and touch.Name == "CollectRadius" then
table.remove(takedPositions, table.find(takedPositions, Cube.Position))
RS.Remotes.Collect:FireServer(ChoosedCube)
AnimateCollect(Cube)
if not script.sound.Playing then script.sound:Play()
CurrencyUI.Cubes.BackgroundColor3 = CubesModule[ChoosedCube].Color
CurrencyUI.Cubes.Icon.ImageColor3 = CubesModule[ChoosedCube].Color
CurrencyUI.Cubes.Gain.Text = "+"..FormatNum.FormatCompact(CubesModule[ChoosedCube].Value, 2)
--XPChange(CubesModule[ChoosedCube].Value/10)
end
end
end)
Cube.Position = spawnArea.Position + Vector3.new(randomX, spawnArea.Size.Y/2 + Cube.Size.Y/2, randomZ)
if table.find(takedPositions, Cube.Position) then Cube:Destroy() return end
table.insert(takedPositions, Cube.Position)
Cube.Parent = CubesFolder
end
connection
task.spawn(function()
while task.wait(0.025) do
SpawnCube()
end
end)
Try using :Connect() instead of :Once() and see if it works.
For example:
local connection
connection = Cube.Touched:Connect(function(touch)
if Players:GetPlayerFromCharacter(touch.Parent) == player and touch.Name == "CollectRadius" then
table.remove(takedPositions, table.find(takedPositions, Cube.Position))
RS.Remotes.Collect:FireServer(ChoosedCube)
AnimateCollect(Cube)
connection:Disconnect()
if not script.sound.Playing then script.sound:Play()
CurrencyUI.Cubes.BackgroundColor3 = CubesModule[ChoosedCube].Color
CurrencyUI.Cubes.Icon.ImageColor3 = CubesModule[ChoosedCube].Color
CurrencyUI.Cubes.Gain.Text = "+"..FormatNum.FormatCompact(CubesModule[ChoosedCube].Value, 2)
--XPChange(CubesModule[ChoosedCube].Value/10
end
end
end)
Because right now it only runs once, even if touch is not the player.
it might be happening due to both of the events not being true.
Try removing that code block and see what it returns, additionally add print statements, to see what the character is returning and what its touching.
And change the AnimateCollect function a little, as its a bit unpredictable.
local function AnimateCollect(cube: Part)
local transp = TS:Create(cube, cubeInfo, {Transparency = 1})
local pos = TS:Create(cube, cubeInfo, {Position = cube.Position + Vector3.new(0, 3, 0)})
transp:Play()
pos:Play()
local connection = {}
connection[1] = transp.Completed:Connect(function()
cube:Destroy()
connection[1]:Disconnect()
if connection[2] then connection[2]:Disconnect() return end
end)
connection[2] = pos.Completed:Connect(function()
cube:Destroy()
connection[2]:Disconnect()
if connection[1] then connection[1]:Disconnect() return end
end)
-- Fall back if fails to disconnect events.
task.wait(1)
connection[1]:Disconnect()
connection[2]:Disconnect()
end
collect radius is a part that creates in player character and follows it with RenderStepped func (acts like player hitbox for collecting cubes)
i also tried commenting out different lines like animate collect and change it to just destroy the part but nothing changes
Its either hitting the players character, continuing with the player, or hitting the collect radius.
Its interesting, try only checking if its touching collect radius, and not the players character, as if its touching collect radius, it should mean that its touching the character, or at least the radius around the character.
and again, add print statements, see what its touching, and what everything is doing.
The last thing I would try is probably switching out the .Once for a .Touched and disconnect it AFTER it verifies that it has been touched by the player.
And I would also use a debounce that uses a table.
As one boolean can be switching very fast, causing it to break.