Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Modify the width and height of RectTransform

Discussion in 'UGUI & TextMesh Pro' started by lzt120, Sep 27, 2014.

  1. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    How Can I modify the width and height of RectTransform ?
     
    catla, Sek19 and belwar like this.
  2. Chudziutki

    Chudziutki

    Joined:
    May 16, 2014
    Posts:
    3
    Try this

    RectTransform rt = UICanvas.GetComponent (typeof (RectTransform)) as RectTransform;
    rt.sizeDelta = new Vector2 (100, 100);

    where UICanvas is Canvas from scene.
     
  3. lzt120

    lzt120

    Joined:
    Apr 13, 2010
    Posts:
    93
    Thanks very much.
     
    donmetapod likes this.
  4. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,248
    A somewhat nicer way to write this (assuming that canvas is a variable with that Canvas from the scene):

    Code (csharp):
    1. RectTransform rt = canvas.GetComponent<RectTransform>();
    2. rt.sizeDelta = new Vector2(100, 100);
     
  5. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    376
    if anyone like me is wondering what the is sizeDelta, here is explanation with pictures.
    Was browsing interwebs, trying to understand what the documentation actually means.
     
  6. Jayno

    Jayno

    Joined:
    Feb 20, 2013
    Posts:
    5
    @Chudziutki thank you
     
  7. lemonLimeBitta

    lemonLimeBitta

    Joined:
    Aug 28, 2014
    Posts:
    2
    Sorry to necropost a bit here,
    Can anyone explain to me why I can't change the rect transforms height directly?

    In @jashan 's example,

    1. Code (CSharp):
      1. RectTransform rt = canvas.GetComponent<RectTransform>();
      2. rt.sizeDelta = new Vector2(100, 100);
      Why can't I do something like:
      Code (CSharp):
      1. RectTransform rt = canvas.GetComponent<RectTransform>();
      2. rt.rect.height= 100;
      or even this doesn't work
      Code (CSharp):
      1. RectTransform rt = canvas.GetComponent<RectTransform>();
      2. rt.sizeDelta.y =  100;
     
  8. mStep

    mStep

    Joined:
    Sep 24, 2012
    Posts:
    34
    That's just not how the properties work. Similarly to how you can't directly set a single axis of a Vector3, you have to set the whole thing at once. But you can reference the current value for whatever you don't want to change. So instead of:

    Code (CSharp):
    1. RectTransform rt = canvas.GetComponent<RectTransform>();
    2. rt.sizeDelta.y =  100;
    It would be:

    Code (CSharp):
    1. RectTransform rt = canvas.GetComponent<RectTransform>();
    2. rt.sizeDelta = new Vector2 (rt.sizeDelta.x, 100);
     
    jeffersonrcgouveia, naviln and Edisyo like this.
  9. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    376
    gonna also try now

    myRecttransf.SetSizeWithCurrentAnchors() ;
    followed by
    myRecttransf.ForceUpdateRectTransforms();

    Need something like this because re-parenting back and forth, and adjusting the recttransform several times during a frame messes up any adjustments done previously, during this frame. Hopefully forceUpdateRectTranasforms will fix these things

    Edit: Well, decided to go with a hybrid:
    Code (CSharp):
    1. // places rect transform to have the same dimensions as 'other', even if they don't have same parent.
    2.     // Relatively non-expensive.
    3.     // NOTICE - also modifies scale of your rectTransf to match the scale of other
    4.     public static void MatchOther(this RectTransform rt,  RectTransform other){
    5.         Vector2 myPrevPivot = rt.pivot;
    6.         myPrevPivot = other.pivot;
    7.         rt.position =  other.position;
    8.  
    9.         rt.localScale = other.localScale;
    10.          
    11.         rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal,  other.rect.width);
    12.         rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical,  other.rect.height);
    13.         //rectTransf.ForceUpdateRectTransforms(); - needed before we adjust pivot a second time?
    14.         rt.pivot = myPrevPivot;
    15.     }
     
    Last edited: Sep 11, 2019
  10. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,054
    So, despite the 16 likes, this is 100% incorrect and should NOT be used:

    ...that will only work in the random situation where your anchors are all at a single point (and it's only lucky that it works). It will fail in most situations.

    As per IgorAherne's posts, as far as I can tell, setting size should only be done using:

    RectTransform.SetSizeWithCurrentAnchors

    NB: the Unity docs are shamefully bad here. They literally don't say what the correct way is to set size, and only tell you that the normally, default, correct way won't work because it's blocked (Unity made the rect read-only).

    EDIT: as of 2018/2019, there's also a minor bug in Unity's implementation of this method. Latest 2018.x version was spamming my console with internal Unity errors. Logged the bug, and had an email this week from Unity saying it'll be fixed soon.
     
    Last edited: Feb 23, 2019
  11. magnitocorp

    magnitocorp

    Joined:
    Dec 5, 2018
    Posts:
    1
    Get the rect of that RectTransform,
    Rect rectContainer = Other.rect;
    rectContainer.height = 'the size you want';
     
  12. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,054
    LOL. Now the definitely, absolutely, incorrect answer has 21 likes. People just don't read. Lazy developers = developers who won't be shipping games.

    EDIT 2020: Over 30 likes. It would be much better if @Chudziutki would come back and edit their answer - at least delete the incorrect info that is breaking people's projects every day :).

    @magnitocorp - you are 100% incorrect. That will achieve literally nothing. There is no way you tried that code - it could never work. We all make mistakes, that's fine, but ... if you're going to give advice, at least TRY IT YOURSELF first and check your understanding before handing out ideas :).
     
    Last edited: Jun 5, 2020
  13. elKarkayu

    elKarkayu

    Joined:
    Mar 23, 2017
    Posts:
    17
    thanks for your replay a436t4ataf!!
     
  14. naviln

    naviln

    Joined:
    Oct 18, 2016
    Posts:
    31
    Legend, thanks so much for sharing the extension method!!
     
    Egil-Sandfeld and IgorAherne like this.
  15. VVad

    VVad

    Joined:
    Aug 5, 2017
    Posts:
    14
    Keep in mind the scale, here I'm getting 50% of the screen size in canvas units :

    Code (CSharp):
    1.  
    2. var sizeDeltaY = 0.5f * Screen.height / canvas.scaleFactor
    3. m_RectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, sizeDeltaY );
    4.  
     
    Last edited: Mar 15, 2020
    Lorrak and a436t4ataf like this.
  16. MaxxVelocity

    MaxxVelocity

    Joined:
    Sep 29, 2019
    Posts:
    3
    I realize I'm late to the party here, but...

    That's exactly how "properties" work. What we have here is a bunch of bugs in Unity that expect the developers to know what the workaround is to assume properties in Unity don't work like they would in general. Having a "setter" explicitly declared, that does not set the value of it's corresponding property, isn't something anyone should ever have to deal with.

    We need some process for fixing the multitude of bugs in the Unity libraries without waiting for the official devs to get around to it. This is a dumpster fire.
     
  17. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,248
    Yes and no. Yes, it's how properties work, and no, this is not a bug in Unity but how C# has been designed. The important thing that apparently has been missing here in this thread is that Vector3 is a struct, so it's "by value" and not "by reference". This difference is really important to understand when working with Unity.

    When you have a property that returns a reference-type (i.e. an object that is an instance of a class, like e.g. a child of MonoBehaviour), you can make changes to the returned instance and because it's just a reference, those changes will actually be done on the original object.

    With "by-value" types (i.e. an object that is an instance of a struct), on the other hand, what you get is a "copy" of the original object, so when you make any changes, those will not be applied on the original object but just on the copy. Fortunately, the C# compiler knows about this and gives you a compile-time error - otherwise, you'd have to deal with very hard to debug runtime errors.

    Unity did work around this with Shuriken (or was it PostProcessing ... or both?), by keeping references to the original objects in most of the types there ... but it's actually quite confusing because it's not standard behavior but quite a hack.

    One reason I believe Unity is using structs a lot is that they are usually kept on the stack instead of the heap, so it's basically a performance optimization at the expense of some convenience. There's more to it but here's some actual profiling ... from 2015, so some of those findings may actually be outdated but the general idea still stands.
     
  18. KiryaRizhiy

    KiryaRizhiy

    Joined:
    Apr 13, 2019
    Posts:
    3
    Igor, spasibo, bratan!
     
    IgorAherne likes this.
  19. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    376
    Blagoslavlayu na profit
     
  20. wolfomat

    wolfomat

    Joined:
    Oct 19, 2014
    Posts:
    20
    so, i am trying to perform this, but none of this works.
    i try to rescale an image place on a canvas.
    What i am calling:
    Code (CSharp):
    1.  rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 2);
    2.             rectTransform.ForceUpdateRectTransforms();
    but the size won't change?

    Turned out i've searched for the wrong element. it's now doing something ;)
     
    Last edited: Oct 17, 2020
unityunity