How to get children's world position in a GridLayoutGroup?

I have a scroll view, in its content object there’s a GridLayoutGroup component(the content object has its own position and scales instead of (0,0,0) or (1,1,1) ), and under it there’re several images. During runtime I want to take out an image and set its parent to other UI object, but I want the image remain its position on screen.

However I tried all the following ways, all ended up with wrong position on screen(the image moved sometimes even off screen).

1 Use SetParent method on the image object(tried both True or false as second parameter):

imageObject.transform.SetParent(otherObj, True);

2 Use SetParent method in the 1st way, then give a position to the image manually, but id does not appear at the mouse position(this code works fine for other objects that are not in a layoutgroup):

imageObject.transform.SetParent(otherObj, True);
var p = Camera.main.ScreenToWorldPoint(Input.mousePosition);
imageObject.transform.position = new Vector3(p.x, p.y, 0);

3 Set the position to its original value after calling SetParent.

imageObject.transform.SetParent(otherObj, True);
var p = imageObject.transform.position;
imageObject.transform.position = new Vector3(p.x, p.y, 0);

4 don’t use any code but during runtime in the editor, manually drag the image out to targeted parent object. Still its position is changed.

5 don’t use any code but during runtime in the editor, manually uncheck the GridLayoutGroup to disable it. Still the image position is changed.

Why the 3rd way is not working? I think probably the transform.position of the image object is not used so the value is not used so the value is not where the position is on screen, or something happened in the end of the frame so my reseting of the position is useless.

More info: my canvas render mode is set to “Screen Space-Camera”. But even changed it to overlay, it remained the same result. Canvas scaler mode is “Scale with Screen Size”, screen match mode is “Expand”.

So what should I do to take out the image out of the GridLayoutGroup but let it stays where it is on screen? Thanks!

After several tests, I found out that the position after you call SetParent(objParent, True); is right; but due to something related with GridLayoutGroup, the position is changed in the time after this and before the end of the frame. So take a record of that position and do whatever you need in other frames.


in main thread:

 imageObject.transform.SetParent(otherObj, True);
 originalPosition = imageObject.transform.position;
 imageObject.SetObjectActive(false); // If not do this, the image might flicker at it's position before put it into the GridLayoutGroup. My guess is that it gets rendered before the AdjustTransInTheEndOfFrame method is executed.

 private IEnumerator AdjustTransInTheEndOfFrame(GameObject obj) 
        yield return new WaitForEndOfFrame();
        obj.transform.position = originalPosition;


Also, it would not be called world position anymore. transform.position is the world position. transform.localPosition is the local position you are talking about.