Script isn't working the way it should be [SOLVED]

Hello, I am working on a game for fun and I’ve come across a issue that I am confused about.

So the way I have the game working right now is I have a model called “PlatformLevels” in workspace. This model contains 6 other models inside that are the different levels to the game.

image

How the system works is that every model has a part called “PlatformDetector”. This detector is a part that when touched will detect what platform level the player is on.

This platform detector has a attribute called “AllowTouch” that is basically a debounce for the touch event so it doesn’t run a million times. By default this is turned off but when the game runs, it is turned on through a server script that loops through each model, finds the detector part, and enables the attribute.

When this detector is touched, a client script will disable the attribute and update the UI above the screen to the current platform that the player is on.

The problem I am having however is that it goes well for the first 3 platforms, but once i get to the 4th one (green platform) it stops working which the only reason why would be that it doesn’t see the attribute as true.

Heres a video to demonstrate it (sorry if its a little choppy)

You can see that it doesn’t update after the 3rd platform and I’m unsure why about it.

^ ^ This here is the system that basically loops through each platform model, finds the detector part, and adds a touch function to it. You can see on line 8 I check if the attribute is true, if it is, everything else after that should run which it does for the first 3 platforms but like I said, on the 4th platform (the green one) it doesn’t run no more which you can see in the video, meaning that it sees it as false even though I checked and it isn’t.

I also tried doing printing and it does show that only the first 3 platforms go through and for the other 3, it says that the attribute is false even though it isn’t.

I have no idea why this is happening as the attributes are true so I don’t understand how it’s seeing it as false. So I’ve come here for an answer.

If you have any questions or need me to clarify on something then please tell me, any help is appreciated :slight_smile:

1 Like

Ok so I understand the issue but I think whatever you’re trying to do you’re overcomplicating it significantly.

Try this:

this is in starter character scripts

local Label = game.Players.LocalPlayer.PlayerGui:WaitForChild("ScreenGui"):WaitForChild("TextLabel")
local PartsFolder = game.Workspace:WaitForChild("Folder")

for i, v in pairs(PartsFolder:GetChildren()) do
	v.Touched:Connect(function(hit)
		if hit and hit:IsDescendantOf(game.Players.LocalPlayer.Character) then
			Label.Text = "Platform "..v.Name
		end
	end)
end

video

Place those parts on their correct levels and it should work

Hey so I just tried your method, I had to edit a little for it to work right but the same issue still seems to be happening.


^^ This is how it currently looks like

I also just did a print to see how many times it finds a Platform Detector which should be six times but it says only three times
image

what are you doing, the only thing in the folder should be the few unique parts not some other stuff. Just like in the video, dont put random stuff in the folder you’re making it way more confusing then it has to be

Based on you stating that AllowTouch is set by the client, the code you’ve given us is inside a LocalScript. It is very possible that the platforms have yet to load, and the script has simply missed them in your GetChildren all. Use this pattern to solve that issue:

local function initializePlatform(platform: Model)
    -- ...
end



for _, platform in PlatformLevels:GetChildren() do
    initializePlatform(platform)
end

PlatformLevels.ChildAdded:Connect(initializePlatform)

I’m gonna try both of ya’ll solutions just give me a second.

Hey I just tried your method and it also didn’t work, I’m not sure if I fully did it right so heres how it currently looks

Its more easier to do what I did because I have to loop through each model to get the Detector. With your way I can’t do that so I have to adjust it a little. Otherwise, I would have to specifically state where each detector is on the script for your method to work correctly.

Bro, just put the parts that when touched should display the new platform level into their own folder.

Ok let me just do it then even and lets see how it goes.

I would use tags to collect all platform hitboxes, then attributes to read the platform level

Just did your method and it doesn’t work

I never used tags before so I would have to learn how those work, but is there really no other way?

It makes no sense at all why it isn’t working, I can’t see the problem at all with this and its so confusing.

Send the place file. I’ll take a deeper look

Are all the children in the detectors just the few parts as shown in my video?

Yes they are just the few parts

Alright here it is!
game cool.rbxl (72.3 KB)

Yeah, so it’s as I figured. Since you’re using a LocalScript, you need to consider load times. The platforms did load, but its children often did not, leaving no “PlatformDetector” instance to be found. I’ve fixed your code and made some additional modifications:

--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players           = game:GetService("Players")


local NUMERICAL_SUFFIX = "%d+$"


local LocalPlayer = Players.LocalPlayer

local Events            = ReplicatedStorage:WaitForChild("Events")
local UpdateLevelStatus = Events:WaitForChild("UpdateLevelStatus")

local Platforms = workspace:WaitForChild("PlatformLevels")
-- I recommend naming the PlatformLevels model "Platforms", and making it a folder.



local function onLivingLocalPlayerTouched(part: BasePart, callback: (Player, BasePart) -> ()): RBXScriptConnection
	return part.Touched:Connect(function(otherPart: BasePart)
		local character = otherPart.Parent :: Model
		
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if not humanoid or humanoid.Health <= 0 then
			return
		end
		
		local player = Players:GetPlayerFromCharacter(character)
		if not player or player ~= LocalPlayer then
			return
		end
		
		callback(player, otherPart)
	end)
end

local function initializePlatform(platform: Model)
	if platform.ClassName ~= "Model" then
		return
	end
	
	-- The detector is already a child of the platform, so you should name it "detector" and leverage the "platform" namespace
	local detector = platform:WaitForChild("PlatformDetector") :: BasePart
	
	onLivingLocalPlayerTouched(detector, function(player: Player)
		if detector:GetAttribute("AllowTouch") then
			detector:SetAttribute("AllowTouch", false)
		else
			return
		end
		
		local suffix = string.match(platform.Name, NUMERICAL_SUFFIX)
		if not suffix then
			error(`Could not determine the level of the platform {platform:GetFullName()}.`)
		end
		
		local platformLevel = player:FindFirstChild("PlatformLevel") :: IntValue
		if not platformLevel then
			error(`Could not find {player}'s PlatformLevel IntValue.`)
		end
		
		platformLevel.Value = tonumber(suffix) :: number
		
		UpdateLevelStatus:Fire(suffix, detector)
	end)
end



for _, platform in Platforms:GetChildren() do
	initializePlatform(platform)
end

Platforms.ChildAdded:Connect(initializePlatform)

Ignore the syntax highlighting. It’s not up-to-date with Luau’s string interpolation

1 Like

Can I have your honest opinion on one thing? Do you seriously think all that is necessary or productive to have a code do a simple thing that I did in like 10 lines?