Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get position of object in Grid Layout

How can I get the actual position of an object in a grid layout? In my current iteration symbolPosition keeps returning 0,0,0.

public void OnPointerClick (PointerEventData eventData)
{
    // Instantiate an object on click and parent to grid
    symbolCharacter = Instantiate(Resources.Load ("Prefabs/Symbols/SymbolImage1")) as GameObject;
    symbolCharacter.transform.SetParent(GameObject.FindGameObjectWithTag("MessagePanel").transform);

    // Set scale of all objects added
    symbolCharacter.transform.localScale = symbolScale;

    // Find position of objects in grid
    symbolPosition = symbolCharacter.transform.position;
    Debug.Log(symbolPosition);
}
like image 624
greyBow Avatar asked Jul 13 '15 12:07

greyBow


2 Answers

The position value wont be updated until the next frame. In order to allow you to make a lot of changes without each one of them causing an entire recalculation of those elements it stores the items that need to be calculated and then updates them at the beginning of the next frame.

so an option is to use a Coroutine to wait a frame and then get the position

public void OnPointerClick (PointerEventData eventData)
{
    // Instantiate an object on click and parent to grid
    symbolCharacter = Instantiate(Resources.Load ("Prefabs/Symbols/SymbolImage1")) as GameObject;
    symbolCharacter.transform.SetParent(GameObject.FindGameObjectWithTag("MessagePanel").transform);

    // Set scale of all objects added
    symbolCharacter.transform.localScale = symbolScale;

    StartCoroutine(CoWaitForPosition());
}

IEnumerator CoWaitForPosition()
{
    yield return new WaitForEndOfFrame();
    // Find position of objects in grid
    symbolPosition = symbolCharacter.transform.position;
    Debug.Log(symbolPosition);
}
like image 172
Colton White Avatar answered Nov 16 '22 18:11

Colton White


This may not have been in the API when this question was asked/answered several years ago, but this appears to work to force the GridLayoutGroup to place child objects on the frame in which child objects are added, thus removing then need for a coroutine.

   for(int i = 0; i < 25; i++){
        GameObject gridCell = Instantiate(_gridCellPrefab);
        gridCell.transform.SetParent(_gridLayoutTransform,false);
    }

    _gridLayoutGroup.CalculateLayoutInputHorizontal();
    _gridLayoutGroup.CalculateLayoutInputVertical();
    _gridLayoutGroup.SetLayoutHorizontal();
    _gridLayoutGroup.SetLayoutVertical();

From here, you can get the positions of the 'gridCells' same frame.

There is another function, which seems like it should fulfill this purpose, but it isn't working for me. The API is pretty quiet on what exactly is going on internally:

LayoutRebuilder.ForceRebuildLayoutImmediate(_gridLayoutTransform);
like image 30
Michael Curtiss Avatar answered Nov 16 '22 17:11

Michael Curtiss