So, I have the following code which runs in an Empty Start function and creates 64 buttons on an 8x8 grid. ‘button’ is an object with an attached script including variables and settings.
for (int x = 0; x < 8; ++x)
{
for (int y = 0; y < 8; ++y)
{
buttons[x, y] = button;
buttons[x, y].xPos = x;
buttons[x, y].yPos = y;
tiles[x, y] = tile;
Instantiate(buttons[x, y], new Vector3(x * 2, 2.5f, y * 2), Quaternion.Euler(x*10, y*10, (x+y)*5));
Instantiate(tiles[x, y], new Vector3(x*2, 1f, y*2), Quaternion.identity);
Debug.Log("Position " + x + " " + y);
}
}
The problem being xPos and yPos are variables in the script attached to the button but I get an error saying these properties don’t exist. I’ve tried public, static, get/set, I can’t get anything to work.
So how should you set variables across scripts when creating objects dynamically? Surely this is done a lot?
Many thanks.
What’s the type of the buttons[,] array? Is it of the type of “the script attached to the button”, as you put it? Could you share the line of code where you declare the array?
Could you also share the code of that script?
Finally, I notice that you’re assigning every element of the 8x8 grid to the same “button” value, then trying to change xPos and yPos on it. Most likely you will just be changing the same instance over and over again, overwriting your previous changes each time.
Creating the array:
public GameObject button; // The prefab is dragged to this variable.
public GameObject[,] buttons = new GameObject[8, 8]; // Then the button with variables is copied to the array.
The only script code on the button prefab itself is the declaration of the 2 variables x/y-pos
public int xpos; public int ypos;
and a transform in the update. The transform in the update works ok.
I’m trying to give each button an identifiable (and easy to reference) value for grid position, not a text tag, because it doesn’t seem possible to return the array position of the button as an element, as when it’s created as a unity object it doesn’t know it’s in an array. It seems.
Should I be approaching this in a different way?
You’re pretty close to the answer, but not quite there.
You seem to have a common misconception/confusion about GameObjects and the components attached to them. GameObjects are basically container objects that don’t have any behavior of their own. Their behavior derives from the Components which are attached to them. If you have attached a component, such as your custom MonoBehavior, to the object, you can’t access properties of that component directly from the object. You have to get a reference to the specific component you care about first. You haven’t shared what your MonoBehavior is called, so for the example code below I’ll use the name “GridPosition”.
You’re also doing another common beginner pitfall of modifying your prefab instead of the instantiated GameObject. Let’s start there:
Inside your loop, you are currently doing this:buttons[x, y] = button;
All this is currently doing is assigning every single element of your grid to the prefab. So the first step is to actually Instantiate your prefab. The newly Instantiated copy is the thing that you actually want to put in your array:
// Note we are using the prefab as the first argument here.
GameObject buttonInstance = Instantiate(button, new Vector3(x * 2, 2.5f, y * 2), Quaternion.Euler(x*10, y*10, (x+y)*5));
buttons[x,y] = buttonInstance;
Now we have an instantiated copy of the prefab, and it’s in the array in the right spot. But the next question is, how do you access your custom variables from your script? Remember I said GameObjects are just containers for Components. We have to get a reference to your component before we can access its variables:
GridPosition gridPosition = buttonInstance.GetComponent<GridPosition>();
gridPosition.xPos = x;
gridPosition.yPos = y;
Now you’re all set! Of course, you’ll want to do something similar with your Tiles as well.
Thank you so much. This feels so different when you’re coming from a code only background, a bit like balancing plates and pealing oranges at the same time!
So that’s got me an array of objects, and if I click one I can report back it’s x/yPos variables. However I’m getting 2 OnMouseDown events firing for each click, one reports the x and y coordinates correctly and the second reports 0, 0 every time.
Is there something odd I need to know about a mouse down, or is some other trickery at play here?