0
\$\begingroup\$

I know questions like these are asked a lot however non of the previously answered ones have helped me. I'm creating a game that spawns a specified number of different objects randomly on a plane. I have each object arranged according to priority that if there isn't enough room for a lower priority object, it just spawns any amount spawn able for that object.

The way I implemented this is that before each object of type is spawned, the maximum amount of the object that can be spawned on the plane is calculated and it keeps within that limit. Then the next calculates the number of objects spawn able after the first object of type has been spawned and keeps within that limit and so on and so on.

However when I the numbers for each objects, if the numbers go above a certain amount the editor stops responding. I've tried multiple ways of changing this but I can't seem to figure it out. Here's my code for the spawner:

 void Spawn( GameObject obj, float height, int num, int max){

    currentObjectsOnBoard = 0;//number of specified objects spawned
    for (int i = 0; true; i++) {
        float x = Random.Range (startX, (startX + boardW));
        float y = height;
        float z = Random.Range (startZ, (startZ - boardH));
        Vector3 temp = new Vector3 (x, y, z);


        Collider[] hitColliders = Physics.OverlapSphere(temp, spacer);
        int a = 0;
        bool free = true;

        while (a < hitColliders.Length)
        {
            if ((hitColliders [a].CompareTag ("Collectable")) || (hitColliders [a].CompareTag ("Obstacle")) || (hitColliders [a].CompareTag ("Hole")) || (hitColliders [a].CompareTag ("Player"))  || (hitColliders [a].CompareTag ("Coin")))  {
                free=false;
                //check if spot is occupied by any of the above, within a radius specified by spacer
            }
            a++;
        }

        if (free) {
            Instantiate (obj, temp, Quaternion.identity);
            currentObjectsOnBoard++;
        } else {
            continue;
        }

        if ((currentObjectsOnBoard == num) || (currentObjectsOnBoard== max-1)) {
            break;
            //if object reaches number specified or if no more can be spawned.
        }

    }

And here's is how I implemented it:

    boardArea = Mathf.Abs (boardW * boardH);
    collectArea = (spacer+1) * (Mathf.PI * collectRad * collectRad);
    playerArea = (spacer+1) * (Mathf.PI * playerRad * playerRad);

    holeArea = (spacer+1) * (Mathf.PI * holeRad * holeRad);
    coinArea = (spacer+1) * (Mathf.PI * coinRad * coinRad);
    obstacleArea = (spacer+1) * (obstacles.transform.localScale.x * obstacles.transform.localScale.z);

    maxCollectablesOnBoard = (int) (((boardArea- (playerArea)) / (collectArea)));
    Spawn (collectable, collectAndCoinHeight, collectNum, maxCollectablesOnBoard);

    tempcollect = currentObjectsOnBoard;//number of collectables spawned if different from numer requested
    maxHolesOnBoard = (int) (((boardArea  - (playerArea) - (tempcollect * collectArea)) / (holeArea)));
    Spawn (hole, holeHeight, holeNum, maxHolesOnBoard);

    temphole = currentObjectsOnBoard;//number of holes spawned if different from numer requested
    maxCoinsOnBoard = (int) (((boardArea  - (playerArea) - (temphole * holeArea) - (tempcollect * collectArea)) / (coinArea)));
    Spawn (coin, collectAndCoinHeight, coinNum, maxCoinsOnBoard);

    tempcoin = currentObjectsOnBoard;//number of coins spawned if different from numer requested
    maxObstaclesOnBoard = (int) (((boardArea  - (playerArea) - (temphole * holeArea) - (tempcollect * collectArea)  - (tempcoin * coinArea)) / (obstacleArea)));
    Spawn (obstacles, obstacleHeight, obstacleNum, maxObstaclesOnBoard);

    tempob = currentObjectsOnBoard;//number of obstacles spawned if different from numer requested
    maxObjectsOnBoard = (int)(((boardArea) / ((temphole * holeArea) + (tempcollect * collectArea)  + (tempcoin * coinArea) + (tempob * obstacleArea) + playerArea)));

I know the code is wrong but I'd really appreciate some help with this. To recap, I'm trying to spawn 4 different types of objects ordered in priority of

collectables

holes

coins

obstacles

An I'm trying to make it such that if one of lower priority has no more room to spawn the number requested, it just spawns the maximum it can spawn. Thank you!

\$\endgroup\$
  • \$\begingroup\$ you shouldn't write all code in your question.please ask clear question and only write important part of your code. \$\endgroup\$ – Seyed Morteza Kamali Apr 16 '17 at 12:36
  • \$\begingroup\$ @smkplus it's not the whole code, only the method and how it was implemented. I'm sorry it's so long, I couldn't figure out how to make it shorter without excluding the important bits \$\endgroup\$ – Drew U Apr 16 '17 at 15:36
1
\$\begingroup\$
for (int i = 0; true; i++)

This is dangerous, because you risk looping in that piece of code forever, and thus freezing the game/editor.

I am not sure how to change your code to make it fit within your game, but I would definitely put a limit to it like this:

for (int i = 0; i < 100; i++)
\$\endgroup\$
  • \$\begingroup\$ Okay, thank you I considered using the maximum number of objects spawnable but I was worried the code wouldn't output the amount wanted or something. I'll put a limit on that now \$\endgroup\$ – Drew U Apr 16 '17 at 15:38
  • \$\begingroup\$ If you are worried about spawning too little objects you can have the function return how many objects were spawned (or similar), then have the function called again later if needed (though I can imagine you prefer spawning all objects at once) \$\endgroup\$ – Demindiro Apr 17 '17 at 8:17
  • \$\begingroup\$ It spawns the objects based on priority, it spawns the first type first, then I call it again for the second type on so on. I did try your suggestion with returning how many were spawned. it still has some kinks but I'm managing it fairly well \$\endgroup\$ – Drew U Apr 18 '17 at 0:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.