Trying to create variable, part too far away

Hey so im making a game where each player can claim a certain area. Some of the areas are too far for the workspace to see when i start a play test, so my script errors.

This is how im calling my variables.

game.Workspace.PlayerAreas:WaitForChild("Area1")
game.Workspace.PlayerAreas:WaitForChild("Area2") -- etc.

For more info, I have it in a local script because those areas contain surface guis with a button. And the intent is to wait for a player to activate the button to claim the are. Everything works fine except for the parts tgat are too far away for tge workspace to see.

How do people usually deal with parts that are too far away like this?

2 Likes

Probably using streaming distance. It gets rid of parts that are far away to improve performance. You can give specific instructions for certain models, iirc, so you could make those parts never stream out.

2 Likes

Oh ok ill look deeper into this and see if it works Does this work based on the proximity of the players to the part or model? And is it automatic or does it involve any extra scripting changes? Like to check if the model in within range or anything?

It’s a Roblox feauture. It can break things, though, specifically in your use case. It’s probably enabled by default. You can exclude models from streaming in/out though.

By break things, you mean like sometimes the part might not appear? Id probably exclude everything thats not neeed immediately in the code. The only reason i need to do this is so i can call the varable early in the script since alot of other things depend on that variable existing.

No, as in the part doesn’t exist; so if you reference it in a script, it’ll break

Roblox’s streaming feature only loads parts of the game world that are near the player to improve performance. Parts that are far away from the player are not loaded immediately when the game starts, which is why your script is unable to find them using WaitForChild.

  • You can use the CollectionService. Tag each of your areas using the Tag Editor, and then use CollectionService:GetInstanceAddedSignal() to run a function whenever an area is loaded into the game. Example:
local CollectionService = game:GetService("CollectionService")

local function onAreaAdded(area)
    -- This function will be run whenever an area is loaded into the game.
    -- You can put your code to initialize the area here.
end

CollectionService:GetInstanceAddedSignal("AreaTag"):Connect(onAreaAdded)

The onAreaAdded function runs whenever an area is loaded into the game, even if it’s far away from the player. Put the code to initialize the area inside this function.

1 Like

This way, you don’t need to wait for all areas to be loaded at the start of the game. Instead, each area will be initialized as soon as it’s loaded.

Sounds like this may be the option for my scenario. Im assuming it should only trigger the function when a new tagged instance is loaded.

And within the function is where i would call the variable. As long as my first character spawns in close enough to my first area then my code should continue this way.

Im still gonna look into streaming distance for other reasons but ill these things a shot and let you guys know what worked for me.

So the Collection Service thing works for when the player gets in range of the part, but only when it was previously out of range. My player spawns in range of the first 5 areas, but it will only print the fifth one (“found A5”). Here’s the test code.

local collectionService = game:GetService("CollectionService")

local function onAreaFound(area)
print("found area")
	if area.Name == "ClaimBoardA1" then
		print("found A1")
	end
	if area.Name == "ClaimBoardA2" then
		print("found A2")
	end
	if area.Name == "ClaimBoardA3" then
		print("found A3")
	end
	if area.Name == "ClaimBoardA4" then
		print("found A4")
	end
	if area.Name == "ClaimBoardA5" then
		print("found A5")
	end
	if area.Name == "ClaimBoardA6" then
		print("found A6")
	end
	if area.Name == "ClaimBoardA7" then
		print("found A7")
	end
	if area.Name == "ClaimBoardA8" then
		print("found A8")
	end
	if area.Name == "ClaimBoardA9" then
		print("found A9")
	end
	if area.Name == "ClaimBoardB" then
		print("found B")
	end
end

collectionService:GetInstanceAddedSignal("ClaimBoard"):Connect(onAreaFound)

So if the collection service finds the first 5 areas right away, would the function not fire 5 times in quick succession?? printing found for each of those areas.

I only want to declare the part as a variable if it is found in the workspace.
This part contains a surface gui and button and I need to have an event listener waiting for a player to activate the button. Because if i don’t, the script will error at the declaration of the variable if it doesn’t exist in the workspace.

Id do a for I, V in pairs loop and do this as a table but the problem is it would only run once. Id have to have that in a while loop or something so its always checking what areas are in that folder. and constantly calling new variables according to which players are near but I feel like that would be bad for my game, seems like not the way to deal with these things.

I wish I could give both you guys solution for this since they were both very helpful answers and each with their own use cases.

Model streaming ended up being the solution, I just put my parts in a model and set the “ModelStreamingMode” to Persistent. Now my script no longer errors upon searching for the part, thanks for the tip.

On the other hand, the Collection Service was a great suggestion. When the player neared a part the event listener fired the script which could be useful in many other situations. However it didn’t work in my situation since it would not fire the script for the parts that were already present in the workspace.

Thanks to both of you for your help

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