Positioning RectTransform

Having a problem positioning some dynamically instantiated prefabs. The process I’m doing here is

  1. Instantiating prefab
  2. Setting its parent to my scene canvas (type Screen Space - Overlay)
  3. Positioning it with transform.Translate

The problem I’m having has to do with when the interface scales. I have the interface set up to run 1920x1080 and when I run it at that resolution everything looks right, however when I run it at a lower resolution the width of my RectTransform doesn’t appear to be correct. It always returns 270 no matter what resolution it’s running at and it makes it so I can’t place my prefabs next to eachother.

Here’s the code I am using:

internal CharacterStatusScript CreateAndAddCharacterStatus(Battleschool.Common.Entities.Contract.Character characterData)
{
    GameObject characterStatus = (GameObject)Instantiate(_characterStatusPrefabType);
    CharacterStatusScript script = (CharacterStatusScript)characterStatus.GetComponent<CharacterStatusScript>();

    script.CharacterData = characterData;

    _characterStatuses.Add(characterStatus);

    characterStatus.transform.SetParent(gameObject.transform, false);

    RectTransform statusTransform = (RectTransform)characterStatus.GetComponent<RectTransform>();

    Vector3 toPosition = new Vector3(statusTransform.rect.size.x * (_characterStatuses.Count - 1), 0);

    statusTransform.transform.Translate(toPosition);
    return script;
}

I want my character status prefabs to be right next to each other with no space in between. The lower the resolution I run at the farther apart they become. I need some way to know their true runtime size. Here is a sample of what I get at a resolution less than 1920x1080.

Here is a sample of what I’m trying for:

Shouldn’t you use RectTransform.achoredPosition to position your elements?

I don’t think so. I want the first prefab in the top-left corner so I put it at 0,0. Then each one thereafter is one prefab’s width in the positive X direction. The anchoredPosition of the canvas would just give me a coordinate a value of the distance from the canvas’ anchor to the canvas’ pivot. I don’t know what I would use that for. I’m not even sure if that’s a valid property on a canvas since the anchor and pivot controls of a canvas are all grayed out in the editor.

I had another hour to look at this and came up with the following solution. Seems to work exactly as expected. I’ll be cleaning it up for reuse later.

float width = Screen.width;

float horizontalRatio = width / 1920f;

Vector3 toPosition = new Vector3((statusTransform.rect.size.x * horizontalRatio) * (_characterStatuses.Count - 1), 0);

They are grayed out because those elements are always relative to containing object in the hierarchy. Canvas is the topmost object and thus cannot be positioned and sized. But all objects below canvas can be anchored and positioned independently. In your case for the prefab I would select top left anchor preset and used anchoredPosition to place the first one at 0,0, second one at prefab.sizeDelta.x, 0 and so on. I don’t have to know sizes of the screen, aspect ratio and such stuff. Definitely simpler.

Your approach sounds interesting. Although I’m not sure if it will work I want to try it but I don’t know what you mean by “select top left anchor preset”. Is this a setting on the canvas you’re talking about?

Documentation. It exists. :slight_smile:
http://docs.unity3d.com/460/Documentation/Manual/UIBasicLayout.html

OH! I had no idea what he was talking about, but of course he was talking about the UI option that allows you to change the rect transform anchor. Didn’t need the documentation, just clarification. I have of course read all of that documentation and watched all of the tutorial vids or I wouldn’t even be here.

All right. Sorry if I jumped to premature conclusions.

2 Likes

Thanks for the apology man although I’ll say I really should have been able to figure out what he meant I just wasn’t in the right frame of mind I guess. My fault.