Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 unity_BGmJcdED5Dqjfw · May 06, 2018 at 03:39 AM · 2dinstantiatelistrandomprocedural

How do I Instantiate a prefab in a randomly generated location specific to tile type (2D Procedural game)

Hey all, newer to Unity and I've been messing around with the board creator script found here and attempting to combine it with the enemy spawn portion of the 2D rogue like tutorial here however I cannot get the "new List" function to work properly. This portion of code to my understanding is supposed to create a list of possible vectors based on the x and y of columns and rows generated and then on my enemy instantiate portion of script it will call random values from the list of possible vectors and assign them to the newly created prefab transforms.

I am trying to make it so that it will spawn a random number of enemies on the board only in the spaces occupied by the tiles assigned to the room array.

Eg)

 private Room[] rooms; 
 public GameObject[] enemyTiles;
 
 number of enemies = random.range (0, rooms.length);
 
 GameObject tileChoice = enemyTile[Random.Range (0, enemyTile.Length)];            
 
 Instantiate(tileChoice, "random position in a randomly generated room", Quaternion.identity);

This is the section of code that should be creating the list of Vectors:

 public List gridPositions = new List  ();
 
     void InitialiseList ()
     {
         //Clear our list gridPositions.
         gridPositions.Clear ();
 
         //Loop through x axis (columns).
         for(int x = 1; x < columns-1; x++)
         {
             //Within each column, loop through y axis (rows).
             for(int y = 1; y < rows-1; y++)
             {
                 //At each index add a new Vector3 to our list with the x and y coordinates of that position.
                 gridPositions.Add (new Vector3(x, y, 0f));
             }
         }
     }

which returns the error: Using the generic type 'System.Collections.Generic.List' requires 1 type arguments

Alternatively if anyone knows how I could randomly generate an enemy during the room and corridor portion of the board creator rather than instantiating them after the rooms have all been created that works as well if not better.

Any help is appreciated :)

Here is the full board creator code for the sake of testing. (note this calls from some of the scripts and assets in the above linked pages and will not properly function without them)

 using System.Collections;
 using UnityEngine;
 using Random = UnityEngine.Random;
 using System;
 using System.Collections.Generic;
 
 public class BoardCreator : MonoBehaviour
 {
     // The type of tile that will be laid in a specific position.
     public enum TileType
     {
         Wall, Floor,
     }
 
 
     public int columns = 100;                                 // The number of columns on the board (how wide it will be).
     public int rows = 100;                                    // The number of rows on the board (how tall it will be).
     public IntRange numRooms = new IntRange (15, 20);         // The range of the number of rooms there can be.
     public IntRange roomWidth = new IntRange (3, 10);         // The range of widths rooms can have.
     public IntRange roomHeight = new IntRange (3, 10);        // The range of heights rooms can have.
     public IntRange corridorLength = new IntRange (6, 10);    // The range of lengths corridors between rooms can have.
     public GameObject[] floorTiles;                           // An array of floor tile prefabs.
     public GameObject[] wallTiles;                            // An array of wall tile prefabs.
     public GameObject[] outerWallTiles;                       // An array of outer wall tile prefabs.
     public GameObject[] enemyTiles;                                 
     public GameObject player;
     private int playerstartX;
     private int playerstartY;
     public int enemyCount = 3;
 
 
 
     private TileType[][] tiles;                               // A jagged array of tile types representing the board, like a grid.
     private Room[] rooms;                                     // All the rooms that are created for this board.
     private Corridor[] corridors;                             // All the corridors that connect the rooms.
     private GameObject boardHolder;                              // GameObject that acts as a container for all other tiles.
 
 
 
     private void Start ()
     {
         // Create the board holder.
         boardHolder = new GameObject("BoardHolder");
 
         SetupTilesArray ();
 
         CreateRoomsAndCorridors ();
 
         SetTilesValuesForRooms ();
         SetTilesValuesForCorridors ();
 
         InstantiateTiles ();
         InstantiateOuterWalls ();
         InstantiatePlayer ();
         LayoutObjectAtRandom (enemyTiles, enemyCount, enemyCount);
 
     }
 
 
     void SetupTilesArray ()
     {
         // Set the tiles jagged array to the correct width.
         tiles = new TileType[columns][];
 
         // Go through all the tile arrays...
         for (int i = 0; i < tiles.Length; i++)
         {
             // ... and set each tile array is the correct height.
             tiles[i] = new TileType[rows];
         }
     }
 
 
     void CreateRoomsAndCorridors ()
     {
         // Create the rooms array with a random size.
         rooms = new Room[numRooms.Random];
 
         // There should be one less corridor than there is rooms.
         corridors = new Corridor[rooms.Length - 1];
 
         // Create the first room and corridor.
         rooms[0] = new Room ();
         corridors[0] = new Corridor ();
 
         // Setup the first room, there is no previous corridor so we do not use one.
         rooms[0].SetupRoom(roomWidth, roomHeight, columns, rows);
 
         // Setup the first corridor using the first room.
         corridors[0].SetupCorridor(rooms[0], corridorLength, roomWidth, roomHeight, columns, rows, true);
 
         for (int i = 1; i < rooms.Length; i++)
         {
             // Create a room.
             rooms[i] = new Room ();
 
             // Setup the room based on the previous corridor.
             rooms[i].SetupRoom (roomWidth, roomHeight, columns, rows, corridors[i - 1]);
 
             // If we haven't reached the end of the corridors array...
             if (i < corridors.Length)
             {
                 // ... create a corridor.
                 corridors[i] = new Corridor ();
 
                 // Setup the corridor based on the room that was just created.
                 corridors[i].SetupCorridor(rooms[i], corridorLength, roomWidth, roomHeight, columns, rows, false);
             }
 
             //if (i == rooms.Length *.5f)
             //{
             //    Vector3 playerPos = new Vector3 (rooms[i].xPos, rooms[i].yPos, 0);
             //    Instantiate(player, playerPos, Quaternion.identity);
             //}
         }
 
     }
 
 
     void SetTilesValuesForRooms ()
     {
         // Go through all the rooms...
         for (int i = 0; i < rooms.Length; i++)
         {
             Room currentRoom = rooms[i];
 
             // ... and for each room go through it's width.
             for (int j = 0; j < currentRoom.roomWidth; j++)
             {
                 int xCoord = currentRoom.xPos + j;
 
                 // For each horizontal tile, go up vertically through the room's height.
                 for (int k = 0; k < currentRoom.roomHeight; k++)
                 {
                     int yCoord = currentRoom.yPos + k;
 
                     // The coordinates in the jagged array are based on the room's position and it's width and height.
                     tiles[xCoord][yCoord] = TileType.Floor;
                 }
             }
         }
     }
 
 
     void SetTilesValuesForCorridors ()
     {
         // Go through every corridor...
         for (int i = 0; i < corridors.Length; i++)
         {
             Corridor currentCorridor = corridors[i];
 
             // and go through it's length.
             for (int j = 0; j < currentCorridor.corridorLength; j++)
             {
                 // Start the coordinates at the start of the corridor.
                 int xCoord = currentCorridor.startXPos;
                 int yCoord = currentCorridor.startYPos;
 
                 // Depending on the direction, add or subtract from the appropriate
                 // coordinate based on how far through the length the loop is.
                 switch (currentCorridor.direction)
                 {
                 case Direction.North:
                     yCoord += j;
                     break;
                 case Direction.East:
                     xCoord += j;
                     break;
                 case Direction.South:
                     yCoord -= j;
                     break;
                 case Direction.West:
                     xCoord -= j;
                     break;
                 }
 
                 // Set the tile at these coordinates to Floor.
                 tiles[xCoord][yCoord] = TileType.Floor;
             }
         }
     }
 
 
     void InstantiateTiles ()
     {
         // Go through all the tiles in the jagged array...
         for (int i = 0; i < tiles.Length; i++)
         {
             for (int j = 0; j < tiles[i].Length; j++)
             {
                 // ... and instantiate a floor tile for it.
                 InstantiateFromArray (floorTiles, i, j);
 
                 // If the tile type is Wall...
                 if (tiles[i][j] == TileType.Wall)
                 {
                     // ... instantiate a wall over the top.
                     InstantiateFromArray (wallTiles, i, j);
                 }
             }
         }
     }
 
 
     void InstantiateOuterWalls ()
     {
         // The outer walls are one unit left, right, up and down from the board.
         float leftEdgeX = -1f;
         float rightEdgeX = columns + 0f;
         float bottomEdgeY = -1f;
         float topEdgeY = rows + 0f;
 
         // Instantiate both vertical walls (one on each side).
         InstantiateVerticalOuterWall (leftEdgeX, bottomEdgeY, topEdgeY);
         InstantiateVerticalOuterWall(rightEdgeX, bottomEdgeY, topEdgeY);
 
         // Instantiate both horizontal walls, these are one in left and right from the outer walls.
         InstantiateHorizontalOuterWall(leftEdgeX + 1f, rightEdgeX - 1f, bottomEdgeY);
         InstantiateHorizontalOuterWall(leftEdgeX + 1f, rightEdgeX - 1f, topEdgeY);
     }
 
 
     void InstantiateVerticalOuterWall (float xCoord, float startingY, float endingY)
     {
         // Start the loop at the starting value for Y.
         float currentY = startingY;
 
         // While the value for Y is less than the end value...
         while (currentY <= endingY)
         {
             // ... instantiate an outer wall tile at the x coordinate and the current y coordinate.
             InstantiateFromArray(outerWallTiles, xCoord, currentY);
 
             currentY++;
         }
     }
 
 
     void InstantiateHorizontalOuterWall (float startingX, float endingX, float yCoord)
     {
         // Start the loop at the starting value for X.
         float currentX = startingX;
 
         // While the value for X is less than the end value...
         while (currentX <= endingX)
         {
             // ... instantiate an outer wall tile at the y coordinate and the current x coordinate.
             InstantiateFromArray (outerWallTiles, currentX, yCoord);
 
             currentX++;
         }
     }
 
 
     void InstantiateFromArray (GameObject[] prefabs, float xCoord, float yCoord)
     {
         // Create a random index for the array.
         int randomIndex = Random.Range(0, prefabs.Length);
 
         // The position to be instantiated at is based on the coordinates.
         Vector3 position = new Vector3(xCoord, yCoord, 0f);
 
         // Create an instance of the prefab from the random index of the array.
         GameObject tileInstance = Instantiate(prefabs[randomIndex], position, Quaternion.identity) as GameObject;
 
         // Set the tile's parent to the board holder.
         tileInstance.transform.parent = boardHolder.transform;
     }
 
 
     void InstantiatePlayer ()
     {
         playerstartX = Mathf.RoundToInt (columns / 2f);
         playerstartY = Mathf.RoundToInt (rows / 2f);
         Vector3 playerstart = new Vector3 (playerstartX, playerstartY, 0f);
         GameObject player1 = Instantiate(player, playerstart, Quaternion.identity) as GameObject;
 
     }
 
 
     public List gridPositions = new List  ();
 
     void InitialiseList ()
     {
         //Clear our list gridPositions.
         gridPositions.Clear ();
 
         //Loop through x axis (columns).
         for(int x = 1; x < columns-1; x++)
         {
             //Within each column, loop through y axis (rows).
             for(int y = 1; y < rows-1; y++)
             {
                 //At each index add a new Vector3 to our list with the x and y coordinates of that position.
                 gridPositions.Add (new Vector3(x, y, 0f));
             }
         }
     }
 
     Vector3 RandomPosition ()
     {
         //Declare an integer randomIndex, set it's value to a random number between 0 and the count of items in our List gridPositions.
         int randomIndex = Random.Range (0, gridPositions.Count);
 
         //Declare a variable of type Vector3 called randomPosition, set it's value to the entry at randomIndex from our List gridPositions.
         Vector3 randomPosition = gridPositions[randomIndex];
 
         //Remove the entry at randomIndex from the list so that it can't be re-used.
         gridPositions.RemoveAt (randomIndex);
 
         //Return the randomly selected Vector3 position.
         return randomPosition;
     }
 
     void LayoutObjectAtRandom (GameObject[] tileArray, int minimum, int maximum)
     {
         //Choose a random number of objects to instantiate within the minimum and maximum limits
         int objectCount = Random.Range (minimum, maximum+1);
 
         //Instantiate objects until the randomly chosen limit objectCount is reached
         for(int i = 0; i < objectCount; i++)
         {
             //Choose a position for randomPosition by getting a random position from our list of available Vector3s stored in gridPosition
             Vector3 randomPosition = RandomPosition();
 
             //Choose a random tile from tileArray and assign it to tileChoice
             GameObject tileChoice = tileArray[Random.Range (0, tileArray.Length)];
 
             //Instantiate tileChoice at the position returned by RandomPosition with no change in rotation
             Instantiate(tileChoice, randomPosition, Quaternion.identity);
         }
     }
 
     //LayoutObjectAtRandom (enemyTiles, enemyCount, enemyCount);
 }


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
1

Answer by KittenSnipes · May 06, 2018 at 10:12 AM

@unity_BGmJcdED5Dqjfw This should be correct. You never told the list what objects it would be holding and I took an educated guess that it would hold objects of type Vector3. Now it should work. If there are any problems feel free to comment and I will help the best I can. Cheers! :D

     public List<Vector3> gridPositions = new List<Vector3>();
  
      void InitialiseList ()
      {
          //Clear our list gridPositions.
          gridPositions.Clear ();
  
          //Loop through x axis (columns).
          for(int x = 1; x < columns-1; x++)
          {
              //Within each column, loop through y axis (rows).
              for(int y = 1; y < rows-1; y++)
              {
                  //At each index add a new Vector3 to our list with the x and y coordinates of that position.
                  gridPositions.Add (new Vector3(x, y, 0f));
              }
          }
      }
Comment
Add comment · Show 3 · 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 unity_BGmJcdED5Dqjfw · May 06, 2018 at 01:48 PM 0
Share

I had tried this but turns out I forgot to call InitialiseList in my start function so it was there but never being implemented. Adding the Vector3 type and actually initializing the list on start worked perfect. The only thing now is to figure out how to make it only spawn on tiles tagged "floor" as currently they spawn in the wall tiles as well.

avatar image unity_BGmJcdED5Dqjfw · May 06, 2018 at 03:28 PM 0
Share

Figured out how to deter$$anonymous$$e the center of each room created and spawn an enemy in those rooms from the array of enemy tiles so now the number of enemies will be equal to the number of rooms and only spawn on the map where the rooms are located :)

 void EnemySpawner ()
     {
         for (int i = 1; i < rooms.Length; i++) 
         {
             Vector2    room$$anonymous$$iddle = new Vector2 (rooms[i].roomWidth / 2f, rooms[i].roomHeight / 2f);
             Vector2 roomPosition = new Vector2 (rooms [i].xPos, rooms [i].yPos);
             InstantiateFromArray (enemyTiles, (room$$anonymous$$iddle.x + roomPosition.x), (room$$anonymous$$iddle.y + roomPosition.y));
         }
     }

Thanks again for the help :)

(Side note after figuring out a better way to instantiate the enemies I don't even need the List function but I'll be using the list method for other implementations so it was still helpful)

avatar image KittenSnipes unity_BGmJcdED5Dqjfw · May 07, 2018 at 02:13 AM 0
Share

@unity_BGmJcdED5Dqjfw

Im glad I could help and if any more help is needed feel free to comment again :D

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

188 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 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

Choose random prefabs from list? 1 Answer

Random select from array and spawn 1 Answer

How do I Photon Instantiate a scene object randomly from a list of objects? 0 Answers

script not working pls solve it 1 Answer

Random 2D tile engine question 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