• 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 /
  • Help Room /
avatar image
Question by hermioninnyorjustaninny · Aug 27, 2019 at 09:57 PM · instantiaterandomnot workingrandom.range

Random position of asteroids -- Random not randomizing?

I'm having an issue with generating asteroids in random positions, based on the random number generator provided in unity. The rest of the Start() function appears to be working properly, as 99 randomly sized asteroids are being created in the scene, but they are all stacked on top of each other, apparently in the same position. I've tried to run the code with and without the Random.InitState(System.Environment.TickCount) and get the same result either way.

Can anyone tell me what the problem is? Code (C#) is attached below.

Thanks!

using System.Collections; using System.Collections.Generic; using UnityEngine;

public class AsteroidGenerator : MonoBehaviour { //meshes and textures that are loaded at run time public Mesh asteroid1; public Mesh asteroid2; public Mesh asteroid3; public Material lightGrey; public Material darkGrey; public Material rockTexture;

 // Start is called before the first frame update
 void Start()
 {
     Random.InitState(System.Environment.TickCount);
     //function creates 99 asteroids of random size
     int i, counter = 0; 
     for(i = 0; i < 100; ++i)
     {
         //create a new game object, mesh, and material to attach to it
         GameObject theAsteroid = new GameObject("Asteroid" + i);
         Mesh asteroid;
         Material thisMaterial;

         //position where the game object will be placed (random)
         Vector3 pos = generateRandomPos();

         //depending on count, set mesh and material components
         if (counter == 0)
         {
             thisMaterial = lightGrey;
             asteroid = Instantiate(asteroid1, pos, Quaternion.identity);
             ++counter;
         }
         if(counter == 1)
         {
             thisMaterial = darkGrey;
             asteroid = Instantiate(asteroid2, pos, Quaternion.identity);
             ++counter;
         }
         else
         {
             thisMaterial = rockTexture;
             asteroid = Instantiate(asteroid3, pos, Quaternion.identity);
             counter = 0;
         }
         //assign mesh and material components to gameobject
         theAsteroid.AddComponent<MeshFilter>();
         theAsteroid.AddComponent<MeshRenderer>();
         theAsteroid.GetComponent<MeshRenderer>().material = thisMaterial;
         theAsteroid.GetComponent<MeshFilter>().mesh = asteroid; 
           
         //set size of asteroid         
         theAsteroid.transform.localScale = new Vector3(Random.Range(5f, 20f), Random.Range(5f, 20f), Random.Range(5f, 20f));

         //add rigidbody and mesh collider
         theAsteroid.AddComponent<Rigidbody>(); 
         Rigidbody rb = theAsteroid.GetComponent<Rigidbody>();
         rb.useGravity = false;
         MeshCollider coll = theAsteroid.GetComponent<MeshCollider>();
         theAsteroid.transform.parent = this.transform;
     }
 }

 //generates random position based on seed
 Vector3 generateRandomPos()
 {
     //Random.InitState(time);
     float x = Random.Range(-500, 500);
     float y = Random.Range(-100, 100);
     float z = Random.Range(-700, 700);
     return new Vector3(x, y, z);
 }

}

Comment

People who like this

0 Show 0
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
Best Answer

Answer by Bunny83 · Aug 28, 2019 at 04:00 AM

Youre code is very confusing and we don't see all details. However you don't seem to instantiate actual prefabs of asteroids but just Meshes. A Mesh does not have a position that could be set by Instantiate. Passing a position and rotation to instantiate only makes sense when you actually instantiate a gameobject / prefab.


What you do is you create a new gameobject at the start of your loop:

 GameObject theAsteroid = new GameObject("Asteroid" + i);

this gameobject will be at "0,0,0". At no point in your code will you move this gameobject to a different position. You essentially build the entire gameobject from scratch. There's also no point in actually instantiating the Mesh. The mesh of a model can and should be used by several gameobject, otherwise you blow up your graphics memory for no reason.


Your different asteroid types should be prefabs and all the things you setup procedurally can be setup once in the editor when creating the prefabs. If you really do not want to use prefabs and create everything procedurally, you should do this instead:

 void Start()
 {
     Random.InitState(System.Environment.TickCount);
     for(int i = 0; i < 100; ++i)
     {
         //create a new game object, mesh, and material to attach to it
         GameObject theAsteroid = new GameObject("Asteroid" + i);
         Mesh asteroid;
         Material thisMaterial;
         //depending on count, set mesh and material components
         int counter = i%3;
         if (counter == 0)
         {
             thisMaterial = lightGrey;
             asteroid = asteroid1;
         }
         else if(counter == 1)
         {
             thisMaterial = darkGrey;
             asteroid = asteroid2;
         }
         else
         {
             thisMaterial = rockTexture;
             asteroid = asteroid3;
         }
         //assign mesh and material components to gameobject
         theAsteroid.AddComponent<MeshFilter>().sharedMesh = asteroid; 
         theAsteroid.AddComponent<MeshRenderer>().sharedMaterial = thisMaterial;
           
         //set size of asteroid         
         theAsteroid.transform.localScale = new Vector3(Random.Range(5f, 20f), Random.Range(5f, 20f), Random.Range(5f, 20f));
         // set random position
         theAsteroid.transform.position = generateRandomPos();
 
         //add rigidbody and mesh collider
         theAsteroid.AddComponent<Rigidbody>().useGravity = false; 
         theAsteroid.AddComponent<MeshCollider>();
         theAsteroid.transform.parent = this.transform;
     }
 }


Note instead of using variables asteroid1, asteroid2 and lightGrey; darkGrey, ... You probably want to use an array instead. That way you don't need this if-else chain since you can directly access the mesh / material you want. By using the array length the code will automatically adapt to the number of materials / meshes you assigned in the inspector.


With prefabs the code would be much simpler:

 public Transform[] asteroidPrefabs;
 
 void Start()
 {
     Random.InitState(System.Environment.TickCount);
     for(int i = 0; i < 100; ++i)
     {
         int counter = i%asteroidPrefabs.Length;
         Transform prefab = asteroidPrefabs[counter];
         Transform theAsteroid = Instantiate(prefab,  generateRandomPos(), Quaternion.identity)
         
         //set size of asteroid         
         theAsteroid.localScale = new Vector3(Random.Range(5f, 20f), Random.Range(5f, 20f), Random.Range(5f, 20f));
         theAsteroid.parent = transform;
     }
 }

All the components and setting would simply be setup in Unity. Create 3 prefabs, attach a rigidbody component, set useGravity to false, etc... All you have to do is assign your different prefabs to the "asteroidPrefabs" array.

Comment

People who like this

0 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 hermioninnyorjustaninny · Aug 29, 2019 at 10:52 PM 0
Share

Thank you so much! That solved my problem -- I didn't realize that creating the game object first would set its position. I am just starting out with coding in unity, and wasn't entirely familiar with the concept of a prefab, but that is SO much better. I will definitely use those in the future. Again, thank you for taking the time to help me solve this, I really appreciate it!

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

139 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image 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

C# Instantiate multiple objects at unique positions within a set range 1 Answer

Increase over time, 0 Answers

Random.range game object destroying itself before reaching destroy position.Please help. 1 Answer

Prefab Scripts Not Working After First Spawn? 2 Answers

Color Randomize when object spawn help 0 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