Inconsistent Collision Detection

I want to develop a small game where there is a conveyor belt and when a player passes through one of the doors, they gain / lose some cash.

I have developed this basic system which works perfectly but I’m having issues with how inconsistent the code is. Sometimes, I receive it when going through and other times, I don’t. It is also far less likely to give the reward when moving on the conveyor.

Game with Program: Conveyor tests - Roblox

Grey base is the Conveyor Belt and the third door is supposed to test if I receive the reward without conveyors.

image

Each door uses the same script inside:

local part = script.Parent
local pause = false
local cashValue = script.Parent.CashValue
local symbol = script.Parent.SymbolValue
local textLabel = part.SurfaceGui.Frame.TextLabel

if symbol.Value == true then
	textLabel.TextColor3 = Color3.fromRGB(0, 255, 0)
	textLabel.UIStroke.Color = Color3.fromRGB(0,150,0)
	textLabel.Text = "+" .. tostring(cashValue.Value) 
else
	textLabel.TextColor3 = Color3.fromRGB(255, 0, 0)
	textLabel.UIStroke.Color = Color3.fromRGB(150,0,0)
	textLabel.Text = "-" .. tostring(cashValue.Value) 
end

local function giveCash(otherPart)
	-- Check if the touching part is a player
	if pause then return end

	pause = true
	
	local character = otherPart.Parent
	local player = game.Players:GetPlayerFromCharacter(character)
	
	if player then
		-- Find the leaderstats and cash values
		local leaderstats = player:FindFirstChild("leaderstats")
		if leaderstats then
			local cash = leaderstats:FindFirstChild("Cash")
			if cash then
				if symbol.Value == true then
					cash.Value += cashValue.Value
				else
					cash.Value = cash.Value - cashValue.Value
					if cash.Value < 0 then
						cash.Value = 0
					end
				end
			end
		end
	end
	wait(2)
	pause = false
end

part.Touched:Connect(giveCash)

Format of items inside of Folder.

image

How can I ensure that everytime the player touches / passes through this door, They recieve the cash?

2 Likes

It’s pausing when an accessory or other passes thru the doors. Check that it is a player before you pause.

2 Likes

If i were you, i would make something like this:

for i, door in Doors do
  door.Touched:Connect(function()
    local Reward = door.Reward.Value
    Player.Coins.Value += Reward
  end
end
1 Like

Depending on how quickly the parts go through the green thing, I believe your debounce is a factor. It could be going in too quickly for the debounce to be off cooldown.

Now, testing your game and giving it a 2 second delay before touching the green parts, I’ve noticed that it’s actually pretty consistent. If you wish to keep this delay, here’s what I recommend that you do.

I recommend that you give the player (or character) an attribute. This attribute will be a replacement for the debounce. We will do:

-- when the player touches it:
Player:SetAttribute("pause", true);

-- then we create an asynchronous thread (code that runs separately from your touched function)
-- this is responsible for "unpausing"

task.spawn(function()
   task.wait(2)
   Player:SetAttribute("pause", false);
end)

I hope this helps, and if it doesn’t, let me know and we can solve this together.

EDIT: Place the task.spawn() at the end of the giveCash function.

1 Like

Thank you for the response!

I modified some of the code using your recommendations and now it is far more consistent.

local function giveCash(otherPart)
	-- Check if the touching part is a player
	if pause then return end
	
	local character = otherPart.Parent
	local player = game.Players:GetPlayerFromCharacter(character)
	if player and player:GetAttribute("pause") then
		return
	end		
			
	if player then
		player:SetAttribute("pause", true);
		-- Find the leaderstats and cash values
		local leaderstats = player:FindFirstChild("leaderstats")
		if leaderstats then
			local cash = leaderstats:FindFirstChild("Cash")
			if cash then
				
				
				if symbol.Value == true then
					cash.Value += cashValue.Value
				else
					cash.Value = cash.Value - cashValue.Value
					if cash.Value < 0 then
						cash.Value = 0
					end	
				end
				
				
			end	
		end
		task.spawn(function()
			task.wait(2)
			player:SetAttribute("pause", false);
		end)
	end
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.