Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Naming prefab obects dynamically in loop

Discussion in 'Scripting' started by Arkitekt, Nov 29, 2012.

  1. Arkitekt

    Arkitekt

    Joined:
    Nov 29, 2012
    Posts:
    6
    I have a loop to create a variable sized grid of blocks. Think Final Fantasy Tactics.

    I want to give each block a unique name (unless anyone has a better idea for identifying the blocks at runtime)

    Ideally my first block is Block00, and then 01, 11, 12 and so on.

    here is my code for pumping out the blocks.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GameMaster : MonoBehaviour {
    5.    
    6.     public int mapLength;
    7.     public int mapWidth;
    8.     public Transform tile;
    9.     public Transform player;
    10.    
    11.     void Start () {
    12.        
    13.  
    14.         float scale = 0;
    15.         float heightadj = 0;
    16.         float height = 0;
    17.        
    18.         for (var y = 0; y < mapLength; y++) {
    19.             for (var x = 0; x < mapWidth; x++) {
    20.                 scale = Random.Range(0.5f,0.5f);
    21.                 height = scale;
    22.                 heightadj = scale / 2;
    23.  
    24.                 GameObject block = Instantiate(tile, new Vector3(x* 0.5f,heightadj,y* 0.5f), Quaternion.identity) as GameObject;
    25.                
    26.                 block.transform.localScale = new Vector3(0.5f, height,0.5f);
    27.                 block.name = "block" + x + y;
    28.                
    29.                 if (x == 0  y == 0){
    30.                     Instantiate(player,new Vector3(x* 0.5f,heightadj+height+0.07f,y* 0.5f), Quaternion.identity);
    31.                 }
    32.             }
    33.         }
    34.        
    35.     }
    36.    
    37.     void Update () {
    38.        
    39.    
    40.  
    41.     }
    42. }
    note: the blocks are of variable height with their bottoms at the same point, i already got random working so i made the range constant for the moment, just in case someone wants to point that out.

    cheers.
     
  2. john-essy

    john-essy

    Joined:
    Apr 17, 2011
    Posts:
    464
    i would create a for loop and assign a name to each one, Something like this

    int nameIndex;
    Code (csharp):
    1. for(int i = 0, i < amountOfCubes.Length; i++)
    2. {
    3.         amountOfCubes[i].name == "Cube" + nameIndex;
    4.         nameIndex++;
    5. }
    Something like this. This will not work just psudo code.
     
  3. Arkitekt

    Arkitekt

    Joined:
    Nov 29, 2012
    Posts:
    6
    I dont know why this is. but i need to set all that stuff before i instantiate the object.

    Code (csharp):
    1.  
    2. tile.name = "block_" + x +""+ y;
    3. tile.transform.localScale = new Vector3(0.5f, height,0.5f);
    4. Instantiate(tile, new Vector3(x* 0.5f,heightadj,y* 0.5f), Quaternion.identity);
    all works fine within the loop. keeps the (clone) but i am ok with that.
     
  4. Democre

    Democre

    Joined:
    Mar 31, 2010
    Posts:
    345
    That works because you are modifying the prefab before you Instantiate it.
    Try this way:
    Code (csharp):
    1. GameObject newTile = (GameObject)Instantiate(tile, new Vector3(x* 0.5f,heightadj,y* 0.5f), Quaternion.identity);
    2. newTile.name = "block_" + x +""+ y;
    3. newTile.transform.localScale = new Vector3(0.5f, height,0.5f);
    4. //you can then add this to a list of tiles should you want
    5. //tiles.Add(newTile);
     
    JumpWire likes this.
  5. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    No you don't. Instantiate can return the thing you instantiated.

    Code (csharp):
    1.  
    2. GameObject tileClone = (GameObject)Instantiate(tile, new Vector3(...), Quaternion.identity);
    3. tileClone.transform.localScale = new Vector3(...);
    4. tileClone.name = "block_" + x + "_" + y;
    5.  
    Edit: Democre beat me to it.
     
  6. Arkitekt

    Arkitekt

    Joined:
    Nov 29, 2012
    Posts:
    6
    when i do it the way you guys mention, i get the following error.

    InvalidCastException: Cannot cast from source type to destination type.
    GameMaster.Start () (at Assets/GameMaster.cs:27)

    that line being the GameObject newTile line. and it only spawns 1 cube and exits my loop.





     
  7. Democre

    Democre

    Joined:
    Mar 31, 2010
    Posts:
    345
    Actually it should be cast and typed to Transform (sorry about that) because your prefab object is typed as a Transform.
     
  8. Arkitekt

    Arkitekt

    Joined:
    Nov 29, 2012
    Posts:
    6
    i switched its type to GameObject to match your suggested code. Same error. Was that a bad plan?

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class GameMaster : MonoBehaviour {
    6.    
    7.     public int mapLength;
    8.     public int mapWidth;
    9.     public GameObject tile;
    10.     public Transform player;
    11.    
    12.     // Use this for initialization
    13.     void Start () {
    14.    
    15.        
    16.         Camera.mainCamera.transform.position = new Vector3(-5,6,-5);
    17.        
    18.         float scale = 0;
    19.         float heightadj = 0;
    20.         float height = 0;
    21.        
    22.         for (var y = 0; y < mapLength; y++) {
    23.             for (var x = 0; x < mapWidth; x++) {
    24.                 scale = Random.Range(0.5f,0.5f);
    25.                 height = scale;
    26.                 heightadj = scale / 2;
    27.                 Debug.Log(x + " " + y);
    28.                 GameObject newTile = (GameObject)Instantiate(tile, new Vector3(x* 0.5f,heightadj,y* 0.5f), Quaternion.identity);
    29.                
    30.                 //newTile.name = "block_" + x +""+ y;
    31.  
    32.                 newTile.transform.localScale = new Vector3(0.5f, height,0.5f);
    33.                
    34.                 //tile.name = "block_" + x +""+ y;
    35.                 //tile.transform.localScale = new Vector3(0.5f, height,0.5f);
    36.                 //Instantiate(tile, new Vector3(x* 0.5f,heightadj,y* 0.5f), Quaternion.identity);
    37.                 if (x == 0  y == 0){
    38.                     Instantiate(player,new Vector3(x* 0.5f,heightadj+height+0.07f,y* 0.5f), Quaternion.identity);
    39.                 }
    40.             }
    41.         }
    42.        
    43.     }
    44.    
    45.     // Update is called once per frame
    46.     void Update () {
    47.        
    48.    
    49.  
    50.     }
    51. }
    52.  
     
  9. Democre

    Democre

    Joined:
    Mar 31, 2010
    Posts:
    345
    Did you assign it in the inspector?
    It looks correct to me.
     
  10. Arkitekt

    Arkitekt

    Joined:
    Nov 29, 2012
    Posts:
    6
    certainly did.

    I'm stumped. it looks fine to me too :(

    edit: nm. i somehow linked the tile to it in the script in assests and not the gameobject the script was linked too. that one said "type mismatch" from when i switched to gameobj
     
    Last edited: Nov 29, 2012
  11. Arkitekt

    Arkitekt

    Joined:
    Nov 29, 2012
    Posts:
    6
    My thanks to you two.