# Unity C# Help With Distance Based Spawner

I am having issues creating a spawn system that relies on the distance of the last object spawned from the spawnpoint. I do not want to use a timer to determine when the next object is spawned but will revert to this if needed. Below is some detail about my progress thus far:

The Spawner

The system currently in place works as follows.

1.) The spawner spawns and object.

2.) Once the object is spawned, it is then cached temporarily to track its distance from the spawner.

3.) Once the cached object(spawned) has reached a distance of say 1 meter from the spawnpoint, the cached object is set to null and the spawner spawns another object. And the cycle repeats.

4.) After a target score is reached the system will rest for 3 seconds and the next wave of objects are spawned but with a slight increase in speed.

The Object

Each object currently has a script on it called GameCube which simply transforms the spawned object downward based on a set speed variable (1). On tap the object is destroyed and a point is awarded.

So far the system works as intended but there are 2 issues.

1.) Each object should maintain the same distance between each other regardless of the speed. But each time the speed is increased the gap between the spawned objects gets larger.

2.) If the object is tapped and destroyed before it reaches the required distance from the spawner, there is then no way to determine when to spawn the next object.

(This has been remedied by spawning the objects off screen, therefore when the player sees the objects they are already pass the required distance)

Here is a copy of the spawn code:

public Transform objectToSpawn;
public bool canSpawn;
public float DistanceFromSpawnPoint;
public float MaximumDistanceLimit = 1f;
public Transform lastObjectSpawned;

// Use this for initialization
void Start ()
{
canSpawn = true;
}

// Update is called once per frame
void FixedUpdate ()
{
Spawn();
}

public void Spawn()
{
if (canSpawn && DistanceFromSpawnPoint == 0)
{
var SpawnedObject = Instantiate(objectToSpawn, transform.position, Quaternion.identity);

lastObjectSpawned = SpawnedObject;

canSpawn = false;
}

if (lastObjectSpawned != null)
{
if (!canSpawn && DistanceFromSpawnPoint < MaximumDistanceLimit)
{
DistanceFromSpawnPoint = Vector2.Distance(this.transform.position, lastObjectSpawned.transform.position);

}
else if (!canSpawn && DistanceFromSpawnPoint > MaximumDistanceLimit)
{
lastObjectSpawned = null;
DistanceFromSpawnPoint = 0;
canSpawn = true;
}
}
else
{
canSpawn = true;
}

}


Object:

public class GameCube : MonoBehaviour { [SerializeField] public static float speed = -15.0f;

// Update is called once per frame
void Update()
{
transform.position += transform.up * speed * Time.deltaTime;

if (transform.position.y < -5.5f)
{
Destroy(this.gameObject);
}
}

public void OnMouseDown()
{

if(this.transform.gameObject.tag == "White Cube")
{
Destroy(this.gameObject);
}
}

public void ScoreEvent(int _score)
{
_score++;
}


}

UPDATE:

OK, I have tried a hundred things. I tried Mathf.Abs, I tried Decimals, doubles, I tried Vector3.Distance, I tried SQR Magnitude I tried to round the numbers to an int.

I understand that floats are not all that accurate and when speed is introduced, things get a little more difficult to track. I have been stuck on this problem for almost 2 weeks and I asked on here once and got some good advice above. This led me to tinker with how I was tracking the position among other things.

My latest version is working sorta. I hae a speed value that starts at 1 and caps at 15. The spawning works for the most part up to 10 (about 90%). The gaps are not that noticeable. But 10 and above the gap is not as bad as before but it creates a decent size gap that throws off the entire gameplay.

Anyone see something that I am not seeing? I simply want to spawn and object and track that objects distance from the spawn origin, then spawn another object once that object reaches say 3 meters from the spawn point. The newly spawned object then becomes the tracked object and the cycle continues.

After each wave the speed increases by 1 up to 15.

Is there a way to move an object down by a set/even amount while still using speed?

public void PoolObjects()
{
ObjectPool = new List<GameObject>();

for (int i = 0; i < poolSize; i++)
{
//creates pooled objects
for (int j = 0; j < ObjectsToPool.Count; j++)
{
GameObject clone = (GameObject)Instantiate(ObjectsToPool[j]);
clone.SetActive(false);

}
}
}

#endregion

// Use this for initialization
void Start()
{
spawnInstance = Spawn;
PoolObjects();
//Invoke("Spawn", 3.0f);

}

private void Update()
{
Spawn();
}

private void FixedUpdate()
{
if (lastObjectSpawned != null)
{

returnedMagnitude = GetSqrDistXZ(SpawnPoints[0].transform.position, lastObjectSpawned.transform.position);
}

SpawnCycle();

}

//Get the Object from Pool
public GameObject GetPooledObject()
{
for (int i = 0; i < ObjectPool.Count; i++)
{
if (!ObjectPool[i].activeInHierarchy)
{
return ObjectPool[i];
}
}
return null;
}

//Activate the Retrieved Object
public void Spawn()
{
//Check if I can Spawn
if (canSpawn)
{
//cache the Retrieved Obj
GameObject obj = GetPooledObject();

//if no object has been retrieved the try again
if (obj == null)
return;

//if an object has been found then Enable it for play and set its coordinates
obj.SetActive(true);
obj.transform.position = SpawnPoints[0].transform.position;
obj.transform.rotation = SpawnPoints[0].transform.rotation;

//track the position of the last object spawned
lastObjectSpawned = obj;

//turn off spawner
canSpawn = false;
}
}

//Calculate Distance from spawner using Custom Sqr Magniture instead of Vector Distance (faster??)
public static float GetSqrDistXZ(Vector2 a, Vector2 b)
{
Vector2 vector = new Vector2(0, a.y - b.y);
return vector.sqrMagnitude;
}

//
public void SpawnCycle()
{
/*if (Mathf.Abs(returnedMagnitude - MaximumDistanceLimit) <= 1.0f)
{
canSpawn = true;
//spawnInstance();
Debug.Log(returnedMagnitude);
}*/

if (returnedMagnitude >= MaximumDistanceLimit)
{
Debug.Log(returnedMagnitude);
//turn spawner back on
canSpawn = true;
}

}


}

New contributor
James Williams is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.