Precaution
What i'm going to write here is not a solution to your problem, in my solution, the movement speed of obstacles is constant. Consider it to be a simplified case of your. I just want to show you a possible way to solve this kind of problem.
First you need to define the distance (the space) between 2 obstacle of 2 different columns that will allow the player to dodge. Let's say:
float safeDistance = 10f;
Next you create an array/list that holds references to the last object spawned on each column, like:
Transform[] lastObstacles = new Transform[3];
Make an event that's fired anytime an obstacle is spawned, update the list
void OnObstacleSpawned (Transform obstacle, int onColumn )
{
lastObstacles [onColumn] = obstacle;
}
Assuming that the obstacles move along the vertical axis OY, the distance from the spawn point to the closest obstacle on given column can be easily calculated by
float DistanceSpawnPointToLastObstacle(int column)
{
if( lastObstacles[column] == null ) return float.MaxValue;
return Mathf.Abs(lastObstacles[column].position.y - spawnPoint.position.y);
}
or between two obstacles
float DistanceBetweenObstacles(int column01, int columnt02)
{
if( lastObstacles[column01] == null ) return float.MaxValue;
if( lastObstacles[columnt02] == null ) return float.MaxValue;
return Mathf.Abs(lastObstacles[column01].position.y - lastObstacles[columnt02].position.y);
}
And now make a condition check function that gives the answer that you want to know ;)
bool ShouldISpawnObstalce(int onColumn)
{
switch (onColumn)
{
case (0):
// there is already space to dodge
if (DistanceBetweenObstacles(1, 2) > safeDistance) return true;
// if not then check if there would be enough space between obstacles on column 0 and on column 1
if (DistanceSpawnPointToLastObstacle(1) > safeDistance) return true;
break;
case (1):
if (DistanceSpawnPointToLastObstacle(0) > safeDistance) return true;
if (DistanceSpawnPointToLastObstacle(2) > safeDistance) return true;
break;
case (2):
if (DistanceBetweenObstacles(0, 1) > safeDistance) return true;
if (DistanceSpawnPointToLastObstacle(1) > safeDistance) return true;
break;
}
return false;
}
Hope this somehow helps.
Edit 01:
The whole code block:
// assign in Inspector, spawn points for column 0-1-2
public Transform[] spawnPoints;
public Transform[] obstacles;
private Transform[] lastObstacles = new Transform[3];
private float safeDistance = 10f;
public void SpawnObstacle()
{
int randomColumn = RandomFunction();
if(ShouldISpawnObstalce(randomColumn))
{
int randomObstacleType = RandomFuntion02();
var obstacleToSpawn = obstacles[randomObstacleType];
var spawnedObject = Instantiate(obstacleToSpawn);
// do set-up/ initialization for obstacle here
spawnedObject.position = spawnPoints[randomColumn].position;
//
OnObstacleSpawned(spawnedObject, randomColumn); // you can make an event here for further use
}
}
void OnObstacleSpawned(Transform obstacle, int onColumn)
{
lastObstacles[onColumn] = obstacle;
}
float DistanceSpawnPointToLastObstacle(int column)
{
if (lastObstacles[column] == null) return float.MaxValue;
return Mathf.Abs(lastObstacles[column].position.y - spawnPoints[column].position.y);
}
float DistanceBetweenObstacles(int column01, int columnt02)
{
if (lastObstacles[column01] == null) return float.MaxValue;
if (lastObstacles[columnt02] == null) return float.MaxValue;
return Mathf.Abs(lastObstacles[column01].position.y - lastObstacles[columnt02].position.y);
}
bool ShouldISpawnObstalce(int onColumn)
{
switch (onColumn)
{
case (0):
// there is already space to dodge
if (DistanceBetweenObstacles(1, 2) > safeDistance) return true;
// if not then check if there would be enough space between obstacles on column 0 and on column 1
if (DistanceSpawnPointToLastObstacle(1) > safeDistance) return true;
break;
case (1):
if (DistanceSpawnPointToLastObstacle(0) > safeDistance) return true;
if (DistanceSpawnPointToLastObstacle(2) > safeDistance) return true;
break;
case (2):
if (DistanceBetweenObstacles(0, 1) > safeDistance) return true;
if (DistanceSpawnPointToLastObstacle(1) > safeDistance) return true;
break;
}
return false;
}
RandomFunction of course should return a valid value, like an int from 0 to 3 (exclusive) in case of random column number or an int from 0 to obstacleToSpawn.Length (exclusive) in case of random obstacle choice. Its implementation is all up to you
And dont forget to assign the needed references in inspector.