Object Transform Keeps Getting Set to (0,0,0)

This issue is baffling me, because it seems like it should be the simplest thing.

So I am making a 2D game, and I have an “Tile” object with the following script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Tile : MonoBehaviour
{

    public int x;
    public int y;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    public void Place(int a, int b)
    {
        x = a;
        y = b;
        Debug.Log("Position: " + x + "," + y);
        transform.position = new Vector3(0.748f*x, 0.864f*y + (y % 2)*0.432f, 0);
        Debug.Log("X transformed to: " + transform.position.x);
    }

    // Update is called once per frame
    void Update()
    {
        Debug.Log("X is now: " + transform.position.x);
    }
}

However, every instance of this object that I have created ends up back at (0,0,0). As you can see in this script, I added some debug messages for testing. So the Place() function is indeed being called, and the position is apparently changed successfully. However, the debug message in Update() always reports that X is zero.

I did not add any other scripts to the object. I haven’t done very much with this project yet, so there isn’t really much that could be doing this. I only wrote one other script for this project so far, which is the following:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TileGenerator : MonoBehaviour
{
    public int width;
    public int height;
    public GameObject tile;

    // Start is called before the first frame update
    void Start()
    {
        for(int i = 0; i < width; i++)
        {
            for(int j = 0; j < height; j++)
            {
                Instantiate(tile, new Vector3(0, 0, 0), Quaternion.identity);
                tile.GetComponent<Tile>().Place(-1*Mathf.FloorToInt((width-1)/2) + i, -1*Mathf.FloorToInt((height-1)/2) + j);
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

This is attached to a separate object. It instantiates instances of the tile object, and then runs Place() to put them at different coordinates. Every instance of the tile is created as desired, and the “x” and “y” properties are set by place, but their position remains at the origin.

This wouldn’t’ve have made much sense, but I wondered if it was some bizarre property of instantiate that put some modifier onto an object to keep at the position specified when instantiate was called? But no matter what I set the vector in instantiate to, the object would always end up at the origin.

All that said, I do have a workaround. If I put the line

transform.position = new Vector3(0.748f*x, 0.864f*y + (y % 2)*0.432f, 0);

into the Update() function, then the tiles do appear at the proper positions. So I guess this is fine for now, but I would really like to know what is causing this? What could be changing the object’s position to (0,0,0) when I only attached this one script to it? This seems very bizarre to me.

Hi!

I believe the problem is here:

Instantiate(tile, new Vector3(0, 0, 0), Quaternion.identity);
tile.GetComponent<Tile>().Place(-1*Mathf.FloorToInt((width-1)/2) + i, -1*Mathf.FloorToInt((height-1)/2) + j);

The problem is that the tile that gets instantiated is not the one that you are moving. The second line of code will always run on the same tile - the one that you dragged into the inspector - and move it to every position. This is why the debugs show it moving to all positions, but you only finding tiles at 0,0 (and maybe one on the corner).

The fix is rather simple, just store the tile that gets instantiated:

Tile newTile = Instantiate(tile, new Vector3(0, 0, 0), Quaternion.identity).GetComponent<Tile>();
newTile.Place(-1 * Mathf.FloorToInt((width - 1) / 2) + i, -1 * Mathf.FloorToInt((height - 1) / 2) + j);

Hope this helps!