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 Steve L · Feb 15, 2015 at 10:49 AM · prefabrandomaddadjustefficient

How can I modify my script to allow more prefabs?

Hello Unity folks,

I have customized a script for my game but I have a couple of questions about it.

The script I have is choosing the prefab (I have several but the script won't allow me to add more than 1 in the inspector) and is stacking that prefab on itself to end up with an endless game. The game exists of obstacles that the main character has to dodge. This script recognizes the distance the player has traveled and is spawning and deleting the prefabs out of view.

I would like to adjust that script so u can drag more prefabs into the inspector. I would like to adjust the script so it would choose the prefabs randomly.

the inspector looks like this:

alt text

The script I have is:

 using UnityEngine;
 using System.Collections.Generic;
 
 public class LevelManager : MonoBehaviour {
     
     public Transform prefab;
     public int numberOfObjects;
     public float recycleOffset;
     public Vector3 startPosition;
     public Vector3 minSize, maxSize, minGap, maxGap;
     public float minX, maxX;
     
     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 = startPosition;
         for(int i = 0; i < numberOfObjects; i++){
             Recycle();
         }
     }
     
     void Update () {
         if(objectQueue.Peek().localPosition.y + recycleOffset < PlayerMovement.distanceTraveled - 15f){
             Recycle();
         }
     }
     
     private void Recycle () {
         Vector3 scale = new Vector3(
             Random.Range(minSize.y, maxSize.y),
             Random.Range(minSize.x, maxSize.x),
             Random.Range(minSize.z, maxSize.z));
         
         Vector3 position = nextPosition;
         position.y += scale.y * 1f;
         position.x += scale.x * 1f;
         
         Transform o = objectQueue.Dequeue();
         o.localScale = scale;
         o.localPosition = position;
         objectQueue.Enqueue(o);
         
         nextPosition += new Vector3(
             Random.Range(minGap.y, maxGap.y) + scale.y,
             Random.Range(minGap.x, maxGap.x),
             Random.Range(minGap.x, maxGap.x));
         
         if(nextPosition.x < minX){
             nextPosition.x = minX + maxGap.x;
         }
         else if(nextPosition.x > maxX){
             nextPosition.x = maxX - maxGap.x;
         }
     }
 }

The original script was spawning cubes which were also randomly adjusted by size. I managed to turn this off, but that is the reason it is still in the script. If somebody knows how to remove this it would be better and more efficient, but it is not priority :P

Thank you in advance :)

screen-shot-2015-02-15-at-123054-am.png (39.8 kB)
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

1 Reply

· Add your reply
  • Sort: 
avatar image
5

Answer by DiegoSLTS · Feb 15, 2015 at 01:30 PM

Replace:

 public Transform prefab;

with:

 public Transform[] prefabs;

and you'll be able to add more than one prefab in the inspector.

Replace:

 objectQueue.Enqueue((Transform)Instantiate(prefab));

with:

 objectQueue.Enqueue((Transform)Instantiate(prefabs[Random.Range(0,prefabs.Length)]));

and you'll get a random prefab from the list.

To remove the random scaling I think it's enough removing "minSize, maxSize" (this will also remove them from the inspector) and replacing the Recycle method with:

 Vector3 position = nextPosition;
 position.y += 1f;
 position.x += 1f;

 Transform o = objectQueue.Dequeue();
 o.localPosition = position;
 objectQueue.Enqueue(o);

 nextPosition += new Vector3(
 Random.Range(minGap.y, maxGap.y) + 1f,
 Random.Range(minGap.x, maxGap.x),
 Random.Range(minGap.x, maxGap.x));

 if(nextPosition.x < minX){
     nextPosition.x = minX + maxGap.x;
 }
 else if(nextPosition.x > maxX){
     nextPosition.x = maxX - maxGap.x;
 }

(I removed all the references to minSize and maxSize and anything related to the scale, and since you want the scale to be always 1, I replaced things like scale.y and scale.x with just "1f")

Comment
Add comment · Show 9 · 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 Steve L · Feb 16, 2015 at 01:26 AM 0
Share

Hey Diego thank you so much for the quick reply. I am really appreciating your help considering my lacking skills in program$$anonymous$$g. I have applied your code and it is working with randomly choosing the prefabs but it is also distributing the prefabs randomly in the field. Prefab1 goes on a random Y axis as well as the other prefabs. The pairs stay together on that line (prefab1 will follow up itself until there is a gap because of prefab 2 which is somewhere else doing the same thing). Is it possible to put somewhere in the script a code that everything will stick to a fixed Y number or is there a better option?

avatar image DiegoSLTS · Feb 20, 2015 at 02:01 AM 0
Share

I'm not sure what the code's supposed to do, but if you want all the instantiated objects with the same "y" remove this line:

 position.y += 1f;

... and change this:

  nextPosition += new Vector3(
      Random.Range($$anonymous$$Gap.y, maxGap.y) + 1f,
      Random.Range($$anonymous$$Gap.x, maxGap.x),
      Random.Range($$anonymous$$Gap.x, maxGap.x));

... to this:

  nextPosition += new Vector3(
      Random.Range($$anonymous$$Gap.y, maxGap.y) + 1f,
      0,
      Random.Range($$anonymous$$Gap.x, maxGap.x));

I guess it should be enough. Note that I just removed all the things that could change the "y" value of the position.

avatar image Steve L · Feb 20, 2015 at 03:11 PM 0
Share

Hey Diego thanks for the information I think only removing position.y += 1f; did the job. I have another question because my prefabs are spawned random when I press start and for the whole game it will be spawned in that order. Do you maybe know what I have to change to the script that every single prefab-spawn will be random during runtime? :)

avatar image DiegoSLTS · Feb 20, 2015 at 08:51 PM 0
Share

Well, your code recycles enemies when they reach a certain y position and move them back to the enemies queue, that's why you get the same pattern.

If you don't want to recycle you don't really need a queue, you have to destroy an enemy when it goes out of screen and create a new random one. Since your code uses a queue to store references of all enemies you can keep it, but ins$$anonymous$$d of:

     Transform o = objectQueue.Dequeue();
     o.localPosition = position;
     objectQueue.Enqueue(o);

... do:

     Transform o = objectQueue.Dequeue();
     o.Destroy(); // destroy the enemy
     o = (Transform)Instantiate(prefab); //create a new random one
     o.localPosition = position;
     objectQueue.Enqueue(o);

I haven't tested it, but something like that should work.

avatar image Steve L · Feb 21, 2015 at 09:37 PM 0
Share

alt text

I get this error when I apply the code in my script.

screen-shot-2015-02-21-at-103602-pm.png (12.6 kB)
Show more comments

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Instantiate a random prefab at an objects location 3 Answers

Instantiating a random prefab from array. 1 Answer

How to instantiate prefabs between 2 objects like a path 0 Answers

GetComponentInChildren not Working 1 Answer

Randomly pick then create prefab 2 Answers


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