0
\$\begingroup\$

My main character can move horizontally and not vertically. It can move from x = -4 to 4 and z = -4 to 4 (a square area). I don't want objects to spawn where my character can move but every where else.
I wrote the following script. According to me it should have worked perfectly fine. But, I can't figure out why the objects are still spawning in the perimeter where the main character is present.

public class SpawnGameObjects : MonoBehaviour
{
    public float secondsBetweenSpawning = 0.1f;
    public float xMinRange = -25.0f;
    public float xMaxRange = 25.0f;
    public float yMinRange = -5.0f;
    public float yMaxRange = 0.0f;
    public float zMinRange = -25.0f;
    public float zMaxRange = 25.0f;
    public GameObject[] spawnObjects; // what prefabs to spawn

    private float nextSpawnTime;

    void Start ()
    {
        // determine when to spawn the next object
        nextSpawnTime = Time.time+secondsBetweenSpawning;
    }

    void Update ()
    {
        // exit if there is a game manager and the game is over
        if (GameManager.gm) {
            if (GameManager.gm.gameIsOver)
                return;
        }

        // if time to spawn a new game object
        if (Time.time  >= nextSpawnTime) {
            // Spawn the game object through function below
            MakeThingToSpawn ();

            // determine the next time to spawn the object
            nextSpawnTime = Time.time+secondsBetweenSpawning;
        }   
    }

    void MakeThingToSpawn ()
    {
        Vector3 spawnPosition;

        // get a random position between the specified ranges
        spawnPosition.x = Random.Range (xMinRange, xMaxRange);
        spawnPosition.y = Random.Range (yMinRange, yMaxRange);
        spawnPosition.z = Random.Range (zMinRange, zMaxRange);
        if ((spawnPosition.z < 4 && spawnPosition.z > -4) || (spawnPosition.x < 4 && spawnPosition.x > -4)) 
        {
            MakeThingToSpawn ();
        }

        // determine which object to spawn
        int objectToSpawn = Random.Range (0, spawnObjects.Length);

        // actually spawn the game object
        GameObject spawnedObject = Instantiate (spawnObjects [objectToSpawn], spawnPosition, transform.rotation) as GameObject;

        // make the parent the spawner so hierarchy doesn't get super messy
        spawnedObject.transform.parent = gameObject.transform;
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Well, there is a more tricky and easy way to spawn objects in 3D world. You may use this answer. \$\endgroup\$ Feb 13, 2016 at 18:59

1 Answer 1

2
\$\begingroup\$

I think you problem is caused by continuing to execute the method when invalid position is generated:

//is position valid?
if ((spawnPosition.z < 4 && spawnPosition.z > -4) || (spawnPosition.x < 4 && spawnPosition.x > -4)) 
{
    //no -> call again
    MakeThingToSpawn (); //this will likely generate object at valid position
    //...and continue to execute this function after returning from function call above
    // spawning second object originally generated, at invalid position(!)
    return; //add return to quickfix to your problem - it will stop exectuing the rest of the function
}

also I would improve the method a bit - as for now it could(though unlikely) cause stack overflow, crashing the game. Again the problem is MakeThingToSpawn (); recursion. Rather then using recursion, I would translate the result to correct range, I would replace the code above with these two lines:

private static readonly double safeZoneSize = 4.0; //up in definitions
//greater than zero? add the safe zone size, subtract otherwise
spawnPosition.x += spawnPosition.x > 0 ? safeZoneSize : -safeZoneSize ; 
spawnPosition.z += spawnPosition.z > 0 ? safeZoneSize : -safeZoneSize ;

note: you need to compensate the safe zone size in the valid range definition(!)

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .