UI RectTransform Position && Screen Resolution

Hi there! I’ve noticed that the cloned UI images that I instantiate at runtime are misplaced.

Here’s what I have

I’ve got Prefabs that are instantiated via script at runtime at a specific position relative to a parent ( which is a child of the main canvas).
Each cloned Prefab is instantiated to the parent’s position, plus the width of all previous clones.
These prefabs are RectTransform with anchor set to center ( setting pivot and/or position too caused an error about threading and UI), the parent is an empty RectTransform.
Canvas’ Canvas Scaler is set to scale with screen size + match width or height.
Here’s a chunk of code:

			clone.transform.position = position; // a Vector defined outside the loop
			slicesRow.Add(clone); //just caching them inside a list
			position += new Vector3(clone.GetComponent<RectTransform>().sizeDelta.x,0,0);

Here’s what I’d like to do

I’d like that my clones kept their right positions when playing with a Screen Resolution different than the one expected.

Here’s what I get

Screen Size expected = ok:

47229-screen-shot-2015-05-29-at-010659.png

Screen Size other = blargh:

47230-screen-shot-2015-05-29-at-010732.png

Thanks for your time, I’m kinda clueless right now and I appreciate your attention

P.S.: about this line ( which is the cause of my problem I guess)

position += new Vector3(clone.GetComponent<RectTransform>().sizeDelta.x,0,0);

I know it’s better to cache that float value instead of calling it every time, I just don’t see the point of optimising a chunk of code that doesn’t get the job done :wink:

I came across this problem as well. If you are going to change a RectTransform’s position or localPosition values you have to scale those values by the CanvasScaler’s referenceResolution. Here’s how I do it:

    private CanvasScaler canvasScaler;

    private Vector2 ScreenScale
    {
        get
        {
            if (canvasScaler == null)
            {
                canvasScaler = GetComponentInParent<CanvasScaler>();
            }

            if (canvasScaler)
            {
                return new Vector2(canvasScaler.referenceResolution.x / Screen.width, canvasScaler.referenceResolution.y / Screen.height);
            }
            else
            {
                return Vector2.one;
            }
        }
    }

I’m not 100% sure what you’re trying to do, but I think this would work:

position += new Vector3(clone.GetComponent<RectTransform>().sizeDelta.x * ScreenScale.x,0,0);

Thanks very much!! I have spent 4 hours to fix this problem. this answer is what I am looking for. I have done some further improvement about that problem. I found the Screen-Canvas Ratio depends on what we set in the inspector, Canvas > Canvas Scaler > Screen Match Mode. If the Match is Width, we just multiply the size.x and size.y value with Screen-Canvas Ratio. It is my code. Tips: it is for 2Dgame.

private CanvasScaler canvasScaler;
private float ScreenCanvasRatio 
{
	get
	{
		if (canvasScaler == null)
		{
			canvasScaler = GameObject.FindObjectOfType<CanvasScaler>();
		}

		if (canvasScaler)
		{
			return Screen.width / canvasScaler.referenceResolution.x;
		}
		else
		{
			return 1;
		}
	}
}

    public Vector3 GetRectTransformFitSize(RectTransform rt)
{
	Vector3 newVector = new Vector3();

	newVector.x = rt.rect.size.x * this.ScreenCanvasRatio;
	newVector.y = rt.rect.size.y * this.ScreenCanvasRatio;
	return newVector;
}