Search Unity

Instantiating an array of Gameobjects Randomly inside a Vector 2 spawn point array.

Discussion in 'Scripting' started by idrog, Oct 21, 2016.

  1. idrog

    idrog

    Joined:
    Jul 30, 2016
    Posts:
    83
    Hello all! What I have currently done is make an grid of X and Y Vector 2 Spawn points and have broken down the array into 5 Columns. Each Column has its own Array with an equal number of spawn points. So I have about 50 total Spawn Points. I have 5 game objects that are also in their own separate array. What I am trying to do is to randomly Instantiate 1 GameObject from my GameObject array("Circaz") to 1 of the Spawn points randomly in each column until all have Columns("ColumnOne"... "ColumnTwo".. ) have been filled each with 1 of the 5 Game Objects. Please Note, I do not want duplicate GameObjects being used but for all of them in the array to be looped through until I have all 5 Game Objects randomly placed in one of the 5 array columns. So In other words, all 5 Gameobjects will be spawned once randomly in each column randomly. I am not gonna clutter this forum with 50 vector 2 spawn or my game object array, so just keep in Mind I do have 50 spawn points in 5 separate arrays(10 Spawn points per array) and 1 Array that has referenced 5 game Objects.(I did type all of that in correctly so I am not gonna put my actual array script but dummy placeholders ) All points are regular whole number ints, no floats. Any idea on how to do this? I posted a for loop below just so you guys dont have to waste your time typing that out along with a Vector2 "positionz" variable

    Lets say the arrays are called:
    Vector2 [] ColumnOne, Vector2 [] ColumnTwo, Vector2 [] Column Three, Vector2 [] Column Four[], Vector2 [] Column Five

    and the Game Object Array is:
    public Gameobject [] Circaz






    for (int i = 0; i <= Circaz.Length; i++)
    {
    Vector2 positionz = new Vector2(What to type here? I know Random.Range May need to be used but have not figured out a way to execute it. Thanks!


    Instantiate( Circaz [ i ] , positionz, Quaternion.identity);
    }
     
    Last edited: Oct 21, 2016
  2. idrog

    idrog

    Joined:
    Jul 30, 2016
    Posts:
    83
    This is the concept I tried applying but I cant even get my objects to spawn with this. I was gonna try manually doing it this way one by one but still cant figure it out. I have defined this in the Start Function and all my arrays right below this which are also in the start function.

    for (int i = 0; i <= Circaz.Length; i++)
    {

    int index = Random.Range(0, RowOne.Length);
    Instantiate(Circaz, ColumnOne[index], Quaternion.identity);

    }
     
  3. Kalladystine

    Kalladystine

    Joined:
    Jan 12, 2015
    Posts:
    227
    Whenever you encounter a problem like this - split it up.
    Let me clarify the question, at least how I understood it:

    You have an array of 5 game objects.
    You have 5 arrays of available positions.
    You want to instantiate a random object from the array (but no duplicates) in each of the arrays with positions.

    So let's split it up, so that there is no double-random anymore:
    What do we want to randomize first?
    The easier answer is - game objects.
    You can use any shuffle algorithm for that, f.e. (uses Linq):
    (untested - I don't have access to IDE now so I'm writing from memory, syntax might be a little off)
    Code (CSharp):
    1. var rnd = new System.Random();
    2. GameObject[] randomizedCollection = yourCollection.OrderBy(x => rnd.Next()).ToArray();
    Now you have randomized the collection, so all it's left to iterate over that collection and spawn objects in each column. It would be easier if the ColumnX arrays would be in a collection themselves, though. If you'd have them in a f.e. a List<Vector2[]> columns:
    Code (CSharp):
    1. List<Vector2[]> columns = new List<Vector2[]>;
    2. columns.Add(ColumnOne);
    3. columns.Add(ColumnTwo);
    4. // add all columns
    Then you do a nested loop:
    Code (CSharp):
    1. for (int i = 0; i < randomizedCollection.Length; ++i)
    2. {
    3.       for (int col = 0; col < columns.Count(); ++col)
    4.       {
    5.             Instantiate(randomizedCollection[i], columns[col][Random.Range(0, columns[col].Length)], Quaternion.identity);
    6.       }
    7. }
    This part might need additional explanation:
    Code (CSharp):
    1. columns[col][Random.Range(0, columns[col].Length)]
    What this does is:
    from columns (List<Vector2[]>) take the item at index col, and from that item (Vector2[]) take the item at index that is randomly generated between 0 and its length (Random.Range for int is exclsuive on the upper bound, so this shouldn't throw any out of bounds).

    This should work, but as I said, I'm writing from memory, so use with care. Either way it should help you move forward as a possible solution.
     
    idrog likes this.
  4. idrog

    idrog

    Joined:
    Jul 30, 2016
    Posts:
    83

    Thanks for the long solution Kallady.. I am a little confused, though I am trying to understand everything you wrote. Perhaps its a little beyond my scope of knowledge and maybe what I was trying to do was a little bit naive. Var is javascript syntax though and I do not know what type of variable "rnd is" and I am confused as to why you are using lists. I know they are more convenient then arrays(and I figured there was an easier and shorthand way of doing it that way) and I am trying to learn them but many of the parts you typed did confuse me. I was perhaps maybe looking for a simpler solution that I Would understand although I know you minimized it too only a few lines so I know the code isnt wrong. Just still confused is all lol.
     
  5. Kalladystine

    Kalladystine

    Joined:
    Jan 12, 2015
    Posts:
    227
    Var is not only javascript - MSDN. It's perfectly valid to use in C#. Short explanation - if the right side of the expression is conclusive about the type (new System.Random() is -> type is System.Random), then this var is the same as typing System.Random rnd = new System.Random();. If the type is not conclusive, or you want to make sure you get a specific type, you should be explicit. It's just a shorthand in this case.

    I used a List there, because you didn't provide your actual code, so it was the easiest way to show that the ColumnX arrays were added to it, this could be done with arrays as well. Essentially what I wanted to have for the code is a collection to iterate over for the nested loop.

    The solution could probably be simpler - I'm not sure why you're setting those 5 arrays with positions in each column (or how), hence I needed to add some extra bits.

    If you have specific questions, please don't hesitate. That's what the forums are for :)