Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by AndrewRyan · May 25, 2015 at 09:48 PM · instantiaterandom2d-platformerlevelrng

Random Spawning system?

Hi,

I'm trying to devise a random but selective spawning system. I want to spawn objects in the level using a random int, but stop spawning a specific one after it has already been spawned a number of times. If it has already spawned, another object should be spawned instead.

Thanks for any and all suggestions!

//-------------------------

 using UnityEngine;
 using System.Collections;
 
 public class Planet 
 {
     public string name;
     public Transform prefab;
     public int number;
 
     public Planet(string newName, Transform newPrefab, int newNumber)
     {
         name = newName;
         prefab = newPrefab;
         number = newNumber;
     }
 }

//--------------------------

 void Awake()
     {
         //add to list
         planets.Add ( new Planet("Start", start, 1));
         planets.Add ( new Planet("End", end, 1));
         planets.Add ( new Planet("Merchant", merchant, 1));
         planets.Add ( new Planet("Poison", poison, poisonCount));
         planets.Add ( new Planet("Repulse", repulse, repulsiveCount));
         planets.Add ( new Planet("Money", money, moneyCount));
 
         //Hex Grid spawning
         float unitLength = ( useAsInnerCircleRadius )? (radius / (Mathf.Sqrt(3)/2)) : radius;
         
         offsetX = unitLength * Mathf.Sqrt(3);
         offsetY = unitLength * 1.5f;
 
         for( int i = 0; i < spawnX; i++ )
         {
             for( int j = 0; j < spawnY; j++ )
             {
                 Vector2 hexpos = HexOffset( i, j );
                 Vector3 pos = new Vector3( hexpos.x, hexpos.y, 0 );
 
                 if(planets.Count > 0)
                     Spawn(pos);
             }
         }
     }
 
     void Spawn(Vector3 position)
     {
         int planet = Random.Range (0, planets.Count);
 
         //if the planet hasn't exceeded its spawn limit, spawn and count down...
         if (CheckNumber(planet))
         {
             Instantiate (planets [planet].prefab, position, Quaternion.identity);
             planets [planet].number --;
         }
         else
             planets.Remove(planets[planet]);
     }
 
     bool CheckNumber(int index)
     {
         bool truth = planets[index].number > 0 ? true : false;
         return truth;
     }
 
     int RandomNumber()
     {
         int number = Random.Range (0, planets.Count);
         return number;
     }








Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image erebel55 · May 26, 2015 at 08:40 PM 2
Share

This is pretty hard to read, a switch inside of a switch? I would recommend getting rid of the ugly switch statements and create a proper data structure to hold the spawned prefabs (and possibly the prefabs that are capable of being spawned). You should take a look at the lists and dictionary tutorial here https://unity3d.com/learn/tutorials/modules/intermediate/scripting/lists-and-dictionaries

avatar image jaja1 · May 27, 2015 at 02:31 AM 1
Share

I keep repeating the same thing over and over. Collections are a very useful thing. Utilize them. Thank you @erebel55

avatar image AndrewRyan · May 27, 2015 at 05:06 AM 0
Share

@erebel55 @jaja1

Thanks for the info guys! I have updated the original post with improved code. The organization was beside the point of confusion: randomly spawning objects but only when the object hasnt already spawned an x number of times.

avatar image Mehul-Rughani · May 27, 2015 at 05:10 AM 1
Share

Then You Have To maintain counter variable for each planet.. :)

avatar image AndrewRyan · May 27, 2015 at 05:25 AM 0
Share

@$$anonymous$$ehul Rughani

Your'e right, $$anonymous$$ehul. Iv'e again updated the code. Now it doesn't spawn if the counter has run out, but that leaves gaps in the level. How can I wait until the check has found a good object in the list to spawn, then resume?

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by zckhyt · May 27, 2015 at 12:20 PM

Okay, so I recommend that you either have a script that keeps track of the number of times a spawn-point has been use, or have this stored as a public integer (or otherwise have a getter method function that returns this). This counter, either way, should increment every time the GameObject is used to be the spawn-point. I'd put it in its own script just to keep things clean.

Then you have a couple of options (assuming these arrays don't have to be sorted in any way):

  1. Sort the array every time a spawn-point is discovered to have spawned its limits to reflect this change. You would need to keep track of two integers: one containing the number of "good" spawn-points and one containing the original number.

  2. Remove the GameObject from the array (optionally add it to another, separate array if you want to not destroy it). You would have to check to see if the index in the array points to null whenever you use it, though.

  3. Keep trying to find a spawn-point until you find one that hasn't reached its maximum count, without removing or sorting anything. This is probably the easiest but the least efficient.

There are more options, but these are the ones that first pop into mind.

To find a random index (to find a random spawn-point) simply use Random.range(0, arraySize - 1);

Here is the basic implementation of the first possible solution (since it might sound a bit weird):

 //Variables
 bool spawnAvailable = true;   //false when the object at index 0 can no longer spawn
 bool sortedArray = false;
 int limit = 5;   //5 spawns per spawner
 int SIZE = 10;   //array will have 10 elements (indexes 0-9)
 int numOfSpawners = SIZE - 1;   //a non-const var to keep track of good spawn-points left
 int index;
 GameObject spawnPointArray[SIZE];
 GameObject bufferObj;
 
 //Spawning
 index = Random.range(0, numOfSpawners);
 if (spawnAvailable && spawnPointArray[index].GetComponent<SpawnCounterScript>().getSpawnCount() < limit)
 {
    //spawn from the spawn-point @ this index
 }
 else if (spawnPointArray[0].GetComponent<SpawnCounterScript>().getSpawnCount() > limit)
    spawnAvailable = false;
 else
 {
    while (sortedArray == false)
    {
       if (spawnPointArray[numOfSpawners].GetComponent<SpawnCounterScript>().getSpawnCount() < limit)
       {
          bufferObj = spawnPointArray[numOfSpawners];
          spawnPointArray[numOfSpawners] = spawnPointArray[index];
          spawnPointArray[index] = bufferObj;
          sortedArray = true;
       }
       else
          numOfSpawners--;
    }
    sortedArray = false;   //reset variable
    index = Random.range(0,numOfSpawners);
    //spawn from the spawn-point @ this index
 }

I know the sort could be more efficient, but I was making it simple to save space. One thing to note, if you want to access any of the spawners who exceeded the limit, you could get a random index containing one of them (assuming at least one) with Random.range(numOfSpawners, SIZE - 1);

Sorry this post was so long, but I felt complied to provide a code example of what I meant for the first point in case you actually wanted to use it (to provide a guideline). And hopefully I didn't mess anything up. So if you have any questions (or want to point out any mistakes in something that I totally proof-read...) let me know!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

script not working pls solve it 1 Answer

How to save a scene that you randomly generated as a new level in your build settings? 1 Answer

Problem with Random.range 1 Answer

how can i do that enemy cars start coming up from my 2nd level of the game ? 1 Answer

How to Spawn multiple game object one by one in random order 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges