Issue with changing the part connected to a Touched event

Hi everyone,

Im working on an Obby minigame, where the first player that manages to complete a level is teleported to the next platform that an Obby connects to and from there selects the new level, with the aim of trying to kill all other remaining players.

The issue with my code - that I cannot manage to find what the cause is - is that players can touch the first platform and create a new platform from there. Theoretically, the first platform should not activate the touched event anymore, the newly created platform should. Therefore, I believe the error is that the script is not updating the part the touched event is connected to.

I have tried editing the variables in my code so that the initial platform does not get activated by the touch event at the bottom of my script anymore, and even made separate folders for the “active” platform that should activate the touched event but none of these solutions have worked.

I apologize if this sounds confusing, please feel free to reply so I can clarify any confusion as I would highly appreciate any assistance

Here is the code:

-- Declaring Services

local ServerStorage = game:GetService("ServerStorage")

-- Declaring game Variables

local ValuesFolder = ServerStorage:FindFirstChild("Values")
local AssetsFolder = ServerStorage:FindFirstChild("Assets")
local PlatformsFolder = game.Workspace:FindFirstChild("Platforms")

local CurrentPlatformValue = ValuesFolder:FindFirstChild("CurrentPlatform").Value
local CurrentPlatform = PlatformsFolder:FindFirstChild(CurrentPlatformValue)
local SpawnPlatform = PlatformsFolder:FindFirstChild("SpawnPlatform")

local RecentWinnerName = ValuesFolder:FindFirstChild("RecentWinnerName").Value

-- Declaring script variables

local isTouched = false --debouncing


function placeNextPlatform(currentLevel)
	
	local platform = AssetsFolder:FindFirstChild("Platform"):Clone()
	local newLevel = currentLevel + 1
	
	-- The information below is us defining the new platform's details
	
	platform.Position = Vector3.new(10,0, (70*newLevel)) -- 70 is the increment of each stage. So if you reach level 2, then the platform Z pos will be 140 studs.
	platform.Parent = PlatformsFolder -- Making it visible
	platform.Name = tostring(newLevel) -- 
		
	return newLevel
end

PlatformsFolder:FindFirstChild(tostring(CurrentPlatformValue)).Touched:Connect(function(hit)
	local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
	
	if humanoid and humanoid.Health > 0 and hit.Parent.Name ~= RecentWinnerName and isTouched == false then
		isTouched = true
		
		RecentWinnerName = hit.Parent.Name -- Now we store the name of the player who just completed the stage so they dont activate the new platform
		
		print(CurrentPlatformValue)
		
		-- This function creates the next platform
		local newLevel = placeNextPlatform(CurrentPlatformValue) 
		CurrentPlatformValue = newLevel
		
		print(RecentWinnerName)
		print(CurrentPlatformValue)
		
		-- Updating the variable so the previous platform does not fire this event
		CurrentPlatform = PlatformsFolder:FindFirstChild(tostring(CurrentPlatformValue))
		CurrentPlatform.Transparency = 0.75 -- for debugging purposes, pls remove later! 
		
		local HRP = hit.Parent:FindFirstChild("HumanoidRootPart")
		HRP.Position = Vector3.new(10,0, (70*CurrentPlatformValue)) -- teleporting the player that touched the stage to the next platform where they will select the next stage.
		
		isTouched = false -- keep this at the end for debouncing purposes
	end
end)
1 Like

This will connect a single .Touched event to whatever Part that is when the code runs. Changing CurrentPlatformValue will not change or create a new .Touched event.

If you want to change touched events you can disconnect an old one and connect a new one.

You can disconnect an event from inside the event handler like so

local connection
connection = Part.Touched:Connect(function(hit)
     connection:Disconnect()
end)
3 Likes

This fixed the error, and it does not allow another player to create a new platform when touching the previous platform

However, the new problem is that when a player touches the new “CurrentPlatform”, it does nothing and does not create a new platform

I think that it might be better if I just made a separate script of the touched event, where once the part is touched the script is destroyed and cloned to the new platform that it creates

The above sums it up, what you have to do is disconnect the old event(by storing it in a variable when you connect it, as shown above) and connect a new event. I suggest converting the code inside Touched to a function and naming it onTouched as this can make code more concise for situations like this because you can simply do:

local function onTouched(hit: BasePart)
	--code that runs when .Touched is fired
end
--more lines of code
local connection = Part.Touched:Connect(onTouched)
--some more lines code
connection:Disconnect()
2 Likes

Is there any way I would be able to connect a new event automatically once the new part is created?

First of all, when you mention .Value in code you store the current value of a value object, not the reference to the current one, therefore keeping it constant. With that in mind since you want to modify said value you have to store the instance instead of the property to the variable, that way you can also use the .Changed event to see when the current platform changes:

--not .Value!
local CurrentPlatformValue = ValuesFolder:FindFirstChild("CurrentPlatform")

local function onTouched()
	--the hell you have in your .Touched function
	--replace all CurrentPlatformValue with CurrentPlatformValue.Value
end

local connection
local function onChanged(val)
	if connection then connection:Disconnect() end
	connection = PlatformsFolder:FindFirstChild(tostring(val)).Touched(onTouched)
end

onChanged(CurrentPlatformValue.Value)
CurrentPlatformValue.Changed:Connect(onChanged)
1 Like