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\$ Commented 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.