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 DarksDaemon · Mar 03, 2013 at 09:06 PM · instantiaterandom

Instantiating a random prefab.

So I once asked about this code before with random materials but now I need this for random prefabs and i'm not sure how to achieve it. (It won't work currently as I changed the prefab variable to a list to store the objects in the inspector)

 using UnityEngine;
 using System.Collections.Generic;
 
 public class SkylineManager : MonoBehaviour {
 
     public List<Transform> prefab;
     public int numberOfObjects;
     public float recycleOffset;
     public Vector3 minSize, maxSize, minGap, maxGap;
     public float minY, maxY;
 
     private Vector3 nextPosition;
     private Queue<Transform> objectQueue;
 
     void Start () {
         objectQueue = new Queue<Transform>(numberOfObjects);
         for(int i = 0; i < numberOfObjects; i++){
             objectQueue.Enqueue((Transform)Instantiate(prefab));
         }
         nextPosition = transform.localPosition;
         for(int i = 0; i < numberOfObjects; i++){
             Recycle();
         }
     }
 
     void Update () {
         if(objectQueue.Peek().localPosition.x + recycleOffset < Player.distanceTraveled){
             Recycle();
         }
     }
 
     private void Recycle () {
         Vector3 scale = new Vector3(
             Random.Range(minSize.x, maxSize.x),
             Random.Range(minSize.y, maxSize.y),
             Random.Range(minSize.z, maxSize.z));
 
         Vector3 position = nextPosition;
         position.x += scale.x * 0.5f;
         position.y += scale.y * 0.5f;
 
         Transform o = objectQueue.Dequeue();
         o.localScale = scale;
         o.localPosition = position;
         objectQueue.Enqueue(o);
 
         nextPosition += new Vector3(
             Random.Range(minGap.x, maxGap.x) + scale.x,
             Random.Range(minGap.y, maxGap.y),
             Random.Range(minGap.z, maxGap.z));
 
         if(nextPosition.y < minY){
             nextPosition.y = minY + maxGap.y;
         }
         else if(nextPosition.y > maxY){
             nextPosition.y = maxY - maxGap.y;
         }
     }
 }
Comment
Add comment
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

2 Replies

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

Answer by sacredgeometry · Mar 03, 2013 at 09:10 PM

RIght to explain the code, first start a new scene and do this.

  1. Create a new scene

  2. Add the script to a game object with a visible object like a cube or sphere

  3. populate the prefabs array/List on the object with some cubes of different variations(i tested with cubs with different materials)

  4. set the cubeSpawnPoint transform to an empty game object and stick it close to the player.

  5. run it

Basically what is happening is that its instantiating an object and picking a random object from the prefabs list, its then parenting it to an empty game object so that al the blocks are organised in your hierarchy, then it is moving the blocks to the position of the cumbeSpawnPoint Transform and translating them based of the last cube position an the current cubes size, so in theory this will work with any shape size cubes as long as they are being stacked in the z axis. (i may have over looked something but I will do more testing later to check that this works)

Looping Functionality

I have started to build in looping functionality for you so but got distracted last night, it just involves a switch and an enum (for ease of use). Basically when the enum is on a certain value it stops adding to the blocksInLevel list and receiving a random index of the prefab list for instantiation. It then could either use the current in game blocks and set their position so that you only ever have a certain amount of blocks in game or it can iterate through the blocksInLevel list and instantiate new blocks based on the current sequence.

Pretty simple stuff.

Pastebin link, might be easier to copy and paste from

I have tried to document the script and make it as self documenting as possible, if there are any questions let me know.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class LevelBlockSpawner : MonoBehaviour {
     
     public List<GameObject> prefabs = new List<GameObject>();             // This contains the different type of blocks
     private List<GameObject> blocksInLevel = new List<GameObject>();     // This contains a reference to current configuration of the block in game    
     
     
     private GameObject BlockStorage;                                    // This GameObject is used to organise all the instantiated cubes  
     private Vector3 lastBlockPosition = new Vector3(0,0,0);                //
         
     public Transform cubeSpawnPoint;
     
     private int initialBlockAmount = 12;
     private int blocksAhead = 8;
     private int blockCreateAmount = 3;
     
     private int blockDeleteCounter = 0;
     
     public enum Mode 
     {
         continuous,
         looping
     }
         
     public Mode BlockMode = Mode.continuous;
     
     // INIT
     // -------------------------------------------------------------------------------------------------------------------------------------------
     void Start () {
                 
         BlockStorage = new GameObject("Block Storage"); // Instantiates the block storage object
         
         // Error handeling for if thhe cubeSpawnPoint transform was not chosen  (avoids null reference)
         if(cubeSpawnPoint == null){
             cubeSpawnPoint = this.transform;
         }
         
         // Instantiates n amount of blocks (based on the initialBlockAmoun variable) just to populate the level at the start of game
         for (int i = 0; i < initialBlockAmount; i++) {
             CreateBlock();
         }
                 
 
     }
     // -------------------------------------------------------------------------------------------------------------------------------------------
     
     void Update () {
         
         /*    This if statement checks to see if the players position ( specifically, this game object) has got the size of the cube * blockAhead
          *      distance away form the last block. Essentially blocksAhead variable tests to see if the player is that many blocks away from hitting the end
          * It then creates an amount of blocks based on blockCreateAmount variable ... so 3 which seems to be enough at most speeds.
          */
         
         if(this.transform.position.z >= lastBlockPosition.z - (blocksInLevel[blocksInLevel.Count-1].transform.lossyScale.z * blocksAhead)){
             for (int i = 0; i < blockCreateAmount; i++) {
                 CreateBlock();
                 Destroy(blocksInLevel[blockDeleteCounter]);
                 blockDeleteCounter++;
             }
             
         }
     }
     
     /*
      * This cretes a single block and adds it to the blocksInLevel List <GameObject> : This is done to keep an eye on the order and allow you to remove 
      * Blocks based on their order or loop blocks or slice parts out of the list for isolated selection.
      */
     
     void CreateBlock (){
         try {
             GameObject tmpCube = (GameObject)Instantiate(prefabs[ Random.Range(0, prefabs.Count - 1) ] );
             tmpCube.transform.parent = BlockStorage.transform;
             blocksInLevel.Add(tmpCube);
             tmpCube.transform.position = cubeSpawnPoint.position;             
             tmpCube.transform.Translate(0.0f ,0.0f , lastBlockPosition.z + tmpCube.transform.localScale.z);
             lastBlockPosition = tmpCube.transform.position;
             
             
         } catch{
             print("There is an issue with the prefabs array, make sure it has at is populated and there are no empty slots.");
         }
         
     }
     
     
     // THIS IS FOR DEMONSTRATION YOU MAY REMOVE THIS
     // -------------------------------------------------------------------------------------------------------------------------------------------
     void FixedUpdate()
     {
         float speed = 0.05f;
         rigidbody.AddForce(transform.forward * speed, ForceMode.VelocityChange);
     }
     // -------------------------------------------------------------------------------------------------------------------------------------------
 
     
 }


Comment
Add comment · Show 28 · 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
avatar image DarksDaemon · Mar 03, 2013 at 09:14 PM 0
Share

I really don't mean to sound sarcastic or ungrateful for your answer but if I knew how to do that I would have done it, could you show me how, the notes on such things seem to be a bit sparse for code like this.

avatar image sacredgeometry · Mar 03, 2013 at 09:15 PM 0
Share

I assumed you knew considering theres already a list...i will amend my answer

avatar image DarksDaemon · Mar 03, 2013 at 09:17 PM 0
Share

$$anonymous$$ost of the code I have I understand, but in this and one other case it's more of an assemblage of copied code from various unity answers pages.

avatar image sacredgeometry · Mar 03, 2013 at 09:29 PM 0
Share

Does this help?

avatar image sacredgeometry · Mar 03, 2013 at 09:39 PM 0
Share

alternativly because you already have the transforms you can do the same instantiate but change the prefabList to the "prefab" list you have already but use prefab.gameObject to grab the gameObject.

Show more comments
avatar image
0

Answer by grossindel · Jan 27, 2014 at 09:48 PM

Your code returned an error. ArgumentOutOfRangeException: Argument is out of range. Parameter name: index

Comment
Add comment · Show 1 · 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
avatar image sacredgeometry · Jan 27, 2014 at 10:10 PM 0
Share

This section is for answers and my code is a roughly coded example. Check that you have gameObjects in your prefab array

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

12 People are following this question.

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

Related Questions

How to access property of a prefab before Instantiating. 1 Answer

Make sure objects are not instantiated on each other 2 Answers

C# Spawn Random Object, at Random 2D Location 2 Answers

Drop item from airplane 1 Answer

Instantiate issues 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