Search code examples
unity-game-engineuser-interfaceinstantiation

Unity UI scaling and instanced prefabs


I'm trying to set up UI elements that are instantiated from prefabs. I use SetParent to put them under a UI elements that's directly under the Canvas. The issue is that when the UI scales, these prefabbed elements don't stick to the part of the screen where they need to be. The Canvas is set to Scale with Screen Size and I'm only interested in 16:9 screens, no mobile stuff. Is there a standard way of placing these instanced prefabs so their relative position to everything else would stop changing with the screen resolution?

statFlag = Instantiate(_infoBox);
statFlag.GetComponent<RectTransform>().position = gameObject.GetComponent<RectTransform>().position + new Vector3(-50, -250 - _displayedStats.Count * 50, 0);
statFlag.transform.SetParent(transform, true);
statFlag.transform.localScale = new Vector3(1/statFlag.transform.lossyScale.x, 1/statFlag.transform.lossyScale.y, 1/statFlag.transform.lossyScale.z);

Solution

  • I found the solution. It's not quite as obvious as the cricket symphony on this post seems to suggest. What can be done is to add a copy of the prefab to the project in the unity editor, position it, scale it and then turn it off. This can then be used as a reference for the copies instantiated from code, what you would need to do is match the sizeDelta, localScale and position to the reference object. Any position offsets then just need to be multiplied with the scale of the canvas and all the UI elements instantiated from code will be nicely in place across all screen sizes (potentially discounting non-uniformly scaled sizes - I didn't test that).