Search Unity

Instanciated items don't scale with canvas scaler

Discussion in 'UGUI & TextMesh Pro' started by Ramcat, Apr 22, 2015.

  1. Ramcat

    Ramcat

    Joined:
    Aug 16, 2014
    Posts:
    95
    I have this scene:


    I used this example to build the scrollable buttons which fit into a panel which is the "Content" of a Scroll Rect. (Example: http://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/creating-scroll-lists-at-run-time )

    However the instantiated buttons don't know they are being added to a canvas that is scaled (see below):


    Math wise, what I believe is happening is that the uGUI code is asking the already existing components what size they are, they report that size in the size of the "Reference Resolution" (which is 600X320) and then scale the button to that size BUT the button is added to the scene in World Space co-ordinates and so is out of scale to the rest of the UI (the items scaled by the canvas scaler).

    To me, it seems the SetParent method needs a Boolean to say "yes, scale this item to the parent canvas scaler" or "No, I have already built this asset at the correct scale".

    Anyone know how to fix this problem?
     
    Last edited: Apr 22, 2015
  2. Ramcat

    Ramcat

    Joined:
    Aug 16, 2014
    Posts:
    95
    @SimonDarksideJ This is definitely one for your book. The Unity documentation is too scarce to figure out what is going on here. I tried in LateUpdate to set the sizeDelta to the sizeDelta * canvas.scaleFactor but the button size does not change. I did print out the Vector2 I got from sizeDelta before and after and the one I modified is the correct size. Checked it by printing the screen and manually drawing a box that big on the captured image.

    I've captured the images of both UIs (actually three differently scaled versions) and the button is the same in all three (give or take one pixel and the steadiness of my hand). The reference resolution is 600X320 and the button is 111X83 and scaled it should be 147X84 at a screen resolution of 800X426, but no matter the actual resolution the button is always 111X83.
     
  3. DWilliams

    DWilliams

    Joined:
    Jan 12, 2015
    Posts:
    63
    You mention the SetParent method. It DOES actually have an optional boolean to either scale to the new parent or keep the old scaling. By default I believe it is set to true and will keep the scale at which it was instantiated. So you can try SetParent(parenttransform, false) and see if that works.
     
    Niter88 and Ramcat like this.
  4. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,689
    Thanks @Ramcat, I'll keep that aside for the 2nd edition :D
    Try @DWilliams 's suggestion, it sounds about right (however I think I've tried it before and it didn't make a difference, maybe it's changed now) and see if it makes a difference.

    I've seen another issue on this same forum, where I recommend them to log an issue on it, quick search should find it as it's the same problem.
     
  5. Ramcat

    Ramcat

    Joined:
    Aug 16, 2014
    Posts:
    95
    Boy do I feel sheepish. Although Maybe I shouldn't because the Unity API just gave me a shock.

    Code (CSharp):
    1. aTransform.SetParent(_ItemPanel.transform);
    2. // These calls are NOT equal
    3. aTransform.SetParent(_ItemPanel.transform, false);
    Which I ask, how could they not be? Are there three SetParent outcomes or does SetParent without the Boolean default to true?

    What's worse is the text on the scripting page for SetParent. There is not documentation of the call without the Boolean and the text of what the Boolean does is inconsistent with what it is actually doing.

    "worldPositionStays If true, the parent-relative position, scale and rotation is modified such that the object keeps the same world space position, rotation and scale as before."

    Before what? I'm parenting it for the first time, it does not have a "before" (unless you're talking about design time, which I would never assume). Do you mean the time between instantiation and parenting, as the "before", if so how could the booleanless SetParent method default to true? (You're assuming that the child should not adopt the new parent's properties (Is that the common usage?)?)

    "Description
    Set the parent of the transform.
    This method is the same as the parent property except that it's possible to make the Transform keep its local orientation rather than its global orientation by setting the worldPositionStays parameter to false."

    Because I'm adding this to a parent who controls the position of the child, the child cannot keep its instantiated position - it is moved instantly by the parent. Also does "global orientation" mean "world space"?
     
  6. Ramcat

    Ramcat

    Joined:
    Aug 16, 2014
    Posts:
    95
    The right thing to do. I figure a shoutout to Adam should not be intrusive due to the fact that I'm passing on some information about Unity.
    @Adam Buckner
    As mentioned above I used your tutorial (all your tutorials are awesome) to create a scroll list. I did run into a problem with the canvas scaler though. Your line:
    Code (CSharp):
    1. newButton.transform.SetParent (contentPanel);
    is apparently not the same as:
    Code (CSharp):
    1. newButton.transform.SetParent (contentPanel, false);
    and won't scale the instantiated item. Just thought it would be worth the heads up. Thanks for your tutorials.
     
    votiakovbogdan likes this.
  7. votiakovbogdan

    votiakovbogdan

    Joined:
    Jul 30, 2019
    Posts:
    1
    You save my day!Thank you!