Ad
Still have questions? Join our Discord server and get real time help.
Log in to vote
0

Touched event not firing?

Asked by 12 days ago

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

Log in to vote
0
Answered by 12 days ago

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

0
No, the only ones that were not local weren't inside a function or if statement or loop. Turtleraptor372 0 — 12d
0
oh ok MarcTheRubixQb 22 — 12d
Ad
Log in to vote
0
Answered by 12 days ago
Edited 7 days ago

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

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. Turtleraptor372 0 — 10d
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. SteelMettle1 394 — 10d
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! Turtleraptor372 0 — 7d
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. Turtleraptor372 0 — 7d
View all comments (6 more)
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.. SteelMettle1 394 — 7d
0
So use region3 and loop to make it constantly check? Or are you talking about something else? Turtleraptor372 0 — 5d
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. SteelMettle1 394 — 5d
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. SteelMettle1 394 — 5d
0
Thanks! I don't know much about RenderStepped, if that's what you are talking about. I'll look into it. Turtleraptor372 0 — 3d
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. Turtleraptor372 0 — 3d

Answer this question