How do I only show objects near the player

Hi, I am making a platformer which has spikes and blocks for the player to jump over as the player continuously moves along the platform. However when I make large levels it makes the game run slow which makes it harder to play due to low fps. I am trying to find a way to make the blocks and spikes only appear if they are within a certain distance of the player because that’s the only time they are needed and on the screen, however I am having a lot of trouble with it. I have tried different variations of the following method but I cannot get it to work the way I want. How can I make the obstacle’s game objects active when within a certain distance and inactive when not within that distance? I have also included a picture of a level to make it more clear. Thanks

var blocks : GameObject[];
var spikes : GameObject[];

function Start(){
	blocks = GameObject.FindGameObjectsWithTag("BlockObstacle");
	spikes = GameObject.FindGameObjectsWithTag("Spike");
}

function Update(){
	for(var blocksToDestroy : GameObject in blocks){
		if(transform.position.x - blocksToDestroy.transform.position.x < 20f){
			blocksToDestroy.transform.gameObject.SetActive(true);
		}
		if(transform.position.x - blocksToDestroy.transform.position.x > 20f){
			blocksToDestroy.transform.gameObject.SetActive(true);
		}
	}
	for(var spikesToDestroy : GameObject in spikes){
		if(transform.position.x - spikesToDestroy.transform.position.x < 20f){
			spikesToDestroy.transform.gameObject.SetActive(false);
		}
		if(transform.position.x - spikesToDestroy.transform.position.x > 20f){
			spikesToDestroy.transform.gameObject.SetActive(true);
		}
	}
}

It’s a wide ranging question with lots of potential answers, but in your specific case I would make a single 1-D list of buckets, with each bucket representing a range of your map (perhaps half a screen’s worth, maybe a quarter or full - kind of depends on how large the map is and how expensive your blocks are to update), and if possible simply parent all the blocks and spikes to these buckets.

Then, instead of looping through every single block and spike every frame, you loop through every bucket and test for distance, and activate/deactivate as necessary. If you were able to parent all the blocks and spikes under the buckets then they will all activate and reactive automatically with the bucket. If not, you can (when the bucket gets within or leaves the range only, not every single frame), just loop through all the blocks and spikes in the bucket and set the active state correctly.

A further optimization would be to check these buckets not every single frame, but intermittently via coroutine, since your character assumably isn’t flying around at 100mph, so if buckets turn themselves on when 40 units away but your character only moves 20 units per second you can check only once every 2 seconds and be safe.

More optimization would be to only check the buckets that are adjacent to other active buckets unless your character regularly teleports.

If your map gets really, really, really huge, instead of buckets containing blocks and spikes, you make buckets containing buckets containing blocks and spikes, in which case you should google up a quad tree and implement a 1D version of it, but from your screenshot I think a simple list of ~10-30 buckets full of blocks and spikes hold be easily fast enough.