- Home /
Wrong position when re-instantiating a pooled UI object
I have a a UI object, which is a dialog window with a Panel as a parent UI element. I have created a prefab for this game object. I also have implemented pooling logic so that I am reusing instances of this dialog within the game, instead of always instantiating a new object.
I also have single game object on the scene, where I have created a Canvas element to host any UI elements I need to display. My goal is to be able to instantiate the dialog into the canvas, and as the dialog's rect transform is set to expand to the edges of its container, I expect it to appear "fullscreeen". Here is the code I am using:
Transform dialogTransform = FindPooledInstance(dialogPrefab).transform;
if (!dialogTransform)
{
dialogTranform = Object.Instantiate(dialogPrefab, globalCanvas.gameObject).transform;
}
else
{
dialogTranform.SetParent(globalCanvas, false);
}
In the above code, globalCanvas
is a RectTransform
referring to my global canvas object, and dialogPrefab
is a GameObject
field referring to the prefab I have created for my dialog.
Everything works fine when there is no pooled instance (we enter the if- clause) -- the dialog object is created and placed exactly as I expect it. The problem occurs when I am showing the dialog again, when it gets recovered from the object pool (in the else-clause) -- its position is being changed and it appears partially (or sometimes fully) off-screen.
In other places in my logic, I use the following code to "return" an existing dialog back to the pool:
dialogTransform.gameObject.SetActive(false);
dialogTransform.SetParent(pool, false);
Here, pool
is a Transform
(not a RectTransform
) somewhere in my scene, where I am placing unused pooled objects. I guess the way I do the "return to pool" logic could be causing the problem, but I fail to recognize exactly what I am doing wrong.
Any advice would be appreciated.
I am using Unity 2017.4.
Answer by Harinezumi · Apr 04, 2018 at 10:24 AM
The dialog is getting repositioned and rescaled due to SetParent(..., false)
. It is really confusing when to use false
and true
for the second parameter (I always get it wrong on the first try). Try using true
in both locations, or only when moving it to the pool. Or you could just use transform.parent
property.
Optionally, you could also just call gameObject.SetActive(false)
on it and not move it to the pool, then SetActive(true)
when you need it again.
Well, I have found a lot of references where the SetParent(..., false)
was recommended, and usually was the solution for a similar to $$anonymous$$e problems. Seems in cases like this it is not.
I tried setting it to true
when returning the dialog to the pool. On the second display of the dialog, it got positioned correctly by its lower left corner, but happened to be over-scaled. To solve this, I had to change the code in my else
clause to this:
dialogTranform.SetParent(globalCanvas, false);
dialogTranform.offset$$anonymous$$in = dialogTranform.offset$$anonymous$$ax = 0f;
I am guessing it somehow gets confused by the dimensions set in the container rect transform object, as the incorrect positions seemed to be multiples of the parent rect-transform width and height.
Answer by Gordrik · Apr 04, 2018 at 10:15 AM
It's really confusing, why are you even pooling UI object, instead of set
them active
to true
or false
when needed?
I don't think this amount of code is enough to solve this your way.
Thanks for taking time on this.
I am in need to pool objects on the UI when there are game-related circumstances causing varying number of UI items -- such as slots in player inventory and etc. The dialog example was trivial enough (I hope so), to display the pooling process I am using, and the trouble I am getting it working. I am facing similar issues displaying some of the other pooled UI elements.
Besides my particular case, you are correct, setting the dialog to be active or not is usually enough.
Your answer
![](https://koobas.hobune.stream/wayback/20220612160021im_/https://answers.unity.com/themes/thub/images/avi.jpg)