Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Touched event not firing?

I am trying to code for a Tower Defense game, and i have run across a problem with the elevators to send players to the map(Technically I am using submarines, not elevators). I used a touched event to make the player go into the sub when they touch a box I made. The script then check to find the next seat not occupied, and makes the player sit there and also disables movement. Then, in a local script in StarterCharacter, I used the seated event to make a leave button appear. A local script in the button makes you leave the seat, destroy the seat weld, and enable controls again. The problem occurs when I try to get back in. The touched event does not fire at all, as there are no errors and i put a print() in the fired function, which didn't print. I also went to a teleporting door I made, which works perfectly fine, and the touched event would not fire after leaving the sub for the first time. Here are the three scripts: In a server script inside the box parts:

Entry = script.Parent
Sub = script.Parent.Parent.Submarine
debounce = false
Entry.Touched:Connect(function(Hit)
	if debounce == false then
		debounce = false
local	Humanoid = Hit.Parent:FindFirstChildWhichIsA("Humanoid")
	if Humanoid then
		if Sub.Seat1.Occupant == nil then
			Sub.Seat1:Sit(Humanoid)
			if Sub.Parent.ReadyingForDeployment.Value == false then
				Sub.Parent.ReadyingForDeployment.Value = true
		    end
		elseif Sub.Seat2.Occupant == nil then
			Sub.Seat2:Sit(Humanoid)
			if Sub.Parent.ReadyingForDeployment.Value == false then
				Sub.Parent.ReadyingForDeployment.Value = true
			end
		elseif Sub.Seat3.Occupant == nil then
			Sub.Seat3:Sit(Humanoid)
			if Sub.Parent.ReadyingForDeployment.Value == false then
				Sub.Parent.ReadyingForDeployment.Value = true
			end
		elseif Sub.Seat4.Occupant == nil then
			Sub.Seat4:Sit(Humanoid)
			if Sub.Parent.ReadyingForDeployment.Value == false then
				Sub.Parent.ReadyingForDeployment.Value = true
			end
		elseif Sub.Seat5.Occupant == nil then
			Sub.Seat5:Sit(Humanoid)
			if Sub.Parent.ReadyingForDeployment.Value == false then
				Sub.Parent.ReadyingForDeployment.Value = true
			end
		elseif Sub.Seat6.Occupant == nil then
			Sub.Seat6:Sit(Humanoid)
			if Sub.Parent.ReadyingForDeployment.Value == false then
				Sub.Parent.ReadyingForDeployment.Value = true
			end
		elseif Sub.Seat7.Occupant == nil then
			Sub.Seat7:Sit(Humanoid)
			if Sub.Parent.ReadyingForDeployment.Value == false then
				Sub.Parent.ReadyingForDeployment.Value = true
			end
		elseif Sub.Seat8.Occupant == nil then
			Sub.Seat8:Sit(Humanoid)
			if Sub.Parent.ReadyingForDeployment.Value == false then
				Sub.Parent.ReadyingForDeployment.Value = true
			end
			end
			wait(0.5)
			debounce = false
		end
	end
end)

In a local script inside of StarterCharacter:

Player = game.Players.LocalPlayer
Character = game.Players.LocalPlayer.Character
Humanoid = Character.Humanoid
Humanoid.Seated:Connect(function(active)
	if active then
		local Controls = require(game.Players.LocalPlayer.PlayerScripts:WaitForChild("PlayerModule")):GetControls()
		Controls:Disable()
		Player.PlayerGui.LeaveSub.Enabled = true
	end
end)

In a local script inside of the leave button:

Button = script.Parent
Player = game.Players.LocalPlayer
Humanoid = Player.Character:WaitForChild("Humanoid")

Button.Activated:Connect(function()
	local	CurrentSub = Humanoid.SeatPart.Parent
	local TpReference = CurrentSub.TpRefernce
	local Seat = Humanoid.SeatPart
	Seat:FindFirstChild("SeatWeld"):Destroy()
	Humanoid.Parent.HumanoidRootPart.CFrame = CFrame.new(TpReference.Position)
	Button.Parent.Parent.Enabled = false
	local Controls = require(game.Players.LocalPlayer.PlayerScripts:WaitForChild("PlayerModule")):GetControls()
	Controls:Enable()
end)

My guess is that the

local Controls = require(game.Players.LocalPlayer.PlayerScripts:WaitForChild("PlayerModule")):GetControls()
	Controls:Disable()

is the main problem, but at this point I am at a loss.
Any help is appreciated.

Thanks

2 answers

I think because when your defining the variables your not saying local at all.

2 comments

0

No, the only ones that were not local weren't inside a function or if statement or loop.

0

oh ok

Try adding true inside the Enable parentheses:

Controls:Enable(true)

I also cleaned up the code a bit and gave you two options. First one is more scalable, second one is if you don't mind using a small amount of memory to make things more efficient:

Use this one if you have a ton of objects to check and you don't want to waste memory storing them:

local Entry = script.Parent
local Sub = script.Parent.Parent.Submarine
local debounce = false
Entry.Touched:Connect(function(Hit)
    if debounce == false then
        debounce = false
		local Humanoid = Hit.Parent:FindFirstChildWhichIsA("Humanoid")
		if Humanoid then
			for i, v in pairs(Sub:GetChildren()) do --returns a table of all the children objects of Sub
				if string.sub(v.Name,1,4) == "Seat" then --Checks each children's name and see if it starts with "Seat"
					if Sub[v.Name].Occupant == nil then --Check each Seat to see if it has an Occupant
						Sub.Seat1:Sit(Humanoid)
						if Sub.Parent.ReadyingForDeployment.Value == false then
	                		Sub.Parent.ReadyingForDeployment.Value = true
	          			end
					end
				end
			end
			wait(0.5)
			debounce = false
		end
	end
end)

Use this one if you don't mind using a little extra memory for very fast looping:

local Entry = script.Parent
local Sub = script.Parent.Parent.Submarine
local debounce = false
local seatTable = {
	"Seat1", "Seat2", "Seat3", "Seat4", "Seat5", "Seat6", "Seat7", "Seat8"
}
Entry.Touched:Connect(function(Hit)
    if debounce == false then
        debounce = false
		local Humanoid = Hit.Parent:FindFirstChildWhichIsA("Humanoid")
		if Humanoid then
			for i, v in pairs(seatTable) do 
				if Sub[v].Occupant == nil then --Check each Seat to see if it has an Occupant
					Sub.Seat1:Sit(Humanoid)
					if Sub.Parent.ReadyingForDeployment.Value == false then
                		Sub.Parent.ReadyingForDeployment.Value = true
          			end
				end
			end
			wait(0.5)
			debounce = false
		end
	end
end)

Also, you have a debounce that is never set to anything other than false. To debounce properly, you should set debounce to true as soon as it enters the if statement.

[EDIT] @Turtleraptor372 Efficient position mapping

11 comments

0

Sorry accidentally made the debounce set to false instead of true. For whatever reason, it still wont work. Do i need to put false in the "Controls:Disable()"? What does the true or false do anyways? Thanks.

0

Instead of using Controls:Disable(). Try using Controls:Enable(false). The true and false are just values to its properties. What I think may be currently happening is if you use :Enable and Disable, then both are set to true and it confuses the engine. That's honestly just a guess though.

0

Again, it didn't work. When i said :Enable(false) instead of :Disable(), the touched event wouldn't even fire. I did not see any errors in the output either. Thanks for helping though!

0

I also just tried simply turning the jump power to 0. It did the same thing, but it also would not fire the touched event, even after i put a debounce.

0

I'm at a complete loss then. Typically, I choose not to use touched events since they are very buggy. I'll provide a link to what I use instead, but basically it turns 3D space into 2D space. You can use it as a region check for ambient music and anything the player interacts with if you use subregions, and subregions to those subregions etc..

0

So use region3 and loop to make it constantly check? Or are you talking about something else?

0

It isn't a region3, it's what colbert said in post #14/15. You designate 2 points that are diagonal of eachother to create an area that you can check. You're probably going to need some sort of position check done every frame anyway to prevent exploiters from teleporting/flying/whatever else.

0

Capture on Stepped and do a quick position check, then you can use heartbeat (since it runs after Stepped) to do the mundane "area check" and areas within that area. You can think of it as though you're indexing a 3D space, where the areas you define are the indices. Less processing than a region3 with a loop and it doesn't yield any threads. Region3's really aren't cheap.

0

Thanks! I don't know much about RenderStepped, if that's what you are talking about. I'll look into it.

0

Oh I see. So instead of Region3 use a part and loop through :GetTouchingParts() instead? Or check to see if the player's HRP is between 2 points? I'll try both.

0

The :GetTouchingParts() thing didnt work. Ill just ask a friend. Thanks for the help though!

This discussion is preserved as it was. New answers, comments, and votes are closed.