- Home /
Issues with tracking prefab instances and gameobject naming (JS)
I have a grid based 2D puzzle game that creates the game board using a 2D array and instantiating prefab instances based on the data for each spot in the array. I also have each prefab instance save its location in the array through variables so that it can tell if it is at 0,0 or 2,3 or 4,1. I also am able to then use that to change the value of each grid spot and those surrounding it when clicked on with a mouse. That all works perfectly. My issue is when it comes to changing sprites for the various prefab instances since they all share the same name. I can change the sprite for the one that is clicked on easily enough, but not the one that is next to it without clicking on it as well. Here is the code that I currently have that handles this:
Script1: This is the code that uses the array to set up the puzzle grid and create the objects in game
var obj_BlankSpot : GameObject;
var obj_PlacedBlankOrb : GameObject;
///This will end up placing the correct objects in the level based on gridArray
gridW = gridArray[0].length; //gets the width of the gridArray for the for loops
gridH = gridArray.length; //gets the height of the gridArray for the for loops
for(r = 0; r < gridW; r++)
{
for(c = 0; c < gridH; c++)
{
var currentX = startX + (r*1.44); // this moves newsprites right for each new column being created
var currentY = startY - (c*1.44); // this moves new sprites down for each new row being created
// 1 pixel seems to be .01 unity units. 100 pixels would be 1 unit
// r and c are reversed in the if statements so the squares are placed left to right
if(gridArray[c][r] == 9)
{
Instantiate(obj_BlankSpot, Vector3 (currentX, currentY, 0), Quaternion.identity); //this object is a blank square where a player can place an or
}
else if(gridArray[c][r] == 0)
{
Instantiate(obj_PlacedBlankOrb, Vector3 (currentX, currentY, 0), Quaternion.identity); // this object is a square that hold a blank orb that can be broken
}
}
}
Script2: This is one of the objects that is created by the code above
var gridArrayScript : scr_gridArray;
var xCoord : int;
var yCoord : int;
function Awake()
{
xCoord = gridArrayScript.r; //sets xCoord = to the c value in the loops for the 2D array
yCoord = gridArrayScript.c; //sets yCoord = to the r value in the loops for the 2D array
}
function OnMouseDown()
{
else if (gridArrayScript.gridArray[yCoord][xCoord] == 9) // checks to see if this is an empty square
{
gridArrayScript.gridArray[yCoord][xCoord] = 11; // changes the data for this square to be fire an empty square
}
}
So since all of the objects share the same name as another, I was doing research on how to identify each of them. I found http://answers.unity3d.com/questions/176314/keeping-track-of-multiple-instances-of-one-prefab.html and so I tried creating a temporary game object that named each one with c and r so that they would be named something like gridspace00, gridspace01, gridspace02, etc. However, when I followed that example, the naming convention didn't work and it broke the loops somehow because only one game object was placed instead of the full grid. Here is the code I tried to use to name each object as they were created:
Modified Script1:
gridW = gridArray[0].length; //gets the width of the gridArray for the for loops
gridH = gridArray.length; //gets the height of the gridArray for the for loops
for(r = 0; r < gridW; r++)
{
for(c = 0; c < gridH; c++)
{
var currentX = startX + (r*1.44); // this moves newsprites right for each new column being created
var currentY = startY - (c*1.44); // this moves new sprites down for each new row being created
var currentSpace : GameObject;
// 1 pixel seems to be .01 unity units. 100 pixels would be 1 unit
// r and c are reversed in the if statements so the squares are placed left to right
if(gridArray[c][r] == 9)
{
currentSpace = Instantiate(obj_BlankSpot, Vector3 (currentX, currentY, 0), Quaternion.identity); //this object is a blank square where a player can place an or
currentSpace.name = "gridspace" + c + r;
}
else if(gridArray[c][r] == 0)
{
currentSpace = Instantiate(obj_PlacedBlankOrb, Vector3 (currentX, currentY, 0), Quaternion.identity); // this object is a square that hold a blank orb that can be broken
currentSpace.name = "gridspace" + c + r;
}
}
}
Is there something I am doing wrong? Should I try to name each object in its own Awake() code just like when the xCoord and yCoord variables are saved? Or am I going about this the entirely wrong and is there something easier to help me with this.
I would save the objects you have created inside the Array, you could use a Struct to store both your Int value and a pointer to the GameObject.
Answer by floydtherooster · Oct 13, 2014 at 08:23 PM
So I think I came across a simple solution that seems to work in the bit of testing that I have done. Since the game object scripts can already read and modify the values of the array in the level creation script, I tried adding an Update() function to the game object scripts. Basically it checks its position in the array and changes the sprite based on the value of that position. I don't think it will cause any performance issues with 50 or so objects on the screen running them will it? Here is an example of the code:
var gridArrayScript : scr_gridArray;
var water : Sprite;
function Awake()
{
xCoord = gridArrayScript.r; //sets xCoord = to the c value in the loops for the 2D array
yCoord = gridArrayScript.c; //sets yCoord = to the r value in the loops for the 2D array
}
function Update()
{
if(gridArrayScript.gridArray[yCoord][xCoord] == 20) //checks to see if there is water in the space
{
GetComponent(SpriteRenderer).sprite = water; //changes the sprite to water
}
}
Your answer
Follow this Question
Related Questions
How can I tell what prefab a GameObject belongs to? 2 Answers
Spawn Prefabs 1 Answer
Spawning a prefab at another object's location 3 Answers
How to instantiate a prefab with a script attached? 2 Answers