Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[FREE] RektTransform.cs - Helper extension functions to use RectTransform like in the inspector

Discussion in 'Assets and Asset Store' started by ketura, Sep 16, 2015.

  1. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    UPDATE 26 SEPT 2015: Set up the RT() helper function as an extension to GameObject, Transform, and UIBehavior. This acts like the accessor .transform, but for RectTransform.

    UPDATE 22 SEPT 2015:
    Massive overhaul of the script to cover pretty much everything you might want to do with a RectTransform by introducing functions that accept arbitrary reference points. This means that now you can move your left edge relative to the right edge of the parent, and other sillyness.

    ----

    RectTransform is a flexible and intuitive tool to use - within the inspector. Once you get into code, it's a bit of a learning curve to understand how to translate all the English parameters that you've gotten used to (Left, Top, Width, etc) that the inspector uses to the rather obtuse naming conventions of the script - sizeDelta, offsetMin/offsetMax, none of it is as easy to parse.

    Introducing RektTransform! This helper class applies liberal coatings of extension functions to the RectTransform class to allow you to work with it in a manner much more approximating how you work with it in the inspector.

    Want to set the "Left" position of an edge? myRectTransform.Left(20).

    Want to change the width? myRectTransform.SetWidth(100).

    Want to scoot that control right up to the top of its parent? myRectTransform.MoveTop(0). Oops, forgot about the height of the control itself...better use myRectTransform.MoveTopInside(0) so I don't have to worry about it.

    In addition to the RectTransform extensions, this also adds a convenience RT() function to several common base classes. No more ((RectTransform)mySlider.transform).RT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 20) when all you want is the quick and dirty mySlider.RT().SetWidth(20). This is added to GameObject, UIBehavior, and Transform.

    Now, that said, this library does not have speed as its top priority. No doubt this will be slower than using all the wonderfully verbose built-in methodology, but I think it makes up for it by communicating intent much, much better. If speed is your number-one priority, well, this can be used as a reference to see how to do all that nifty stuff the inspector does, and you can use it to learn how to do it the hard way.

    TO USE: Download the script from this bitbucket page. Include it in your project somewhere, stick "using RektTransform;" at the top of your script, and bam! You're done. Simply use all the included functions as if they were built-in to RectTransform (or your UI controls!)

    As documentation and so you can see what's included, here are all the function headers with brief comments (the UIBehaviour extensions are removed for clarity. All they do is call these functions listed here anyway.)


    Code (CSharp):
    1.  
    2. //All the default anchoring positions.  Note that unlike most grid-based systems, this
    3. // follows the form "Y, X", in accordance with how it is spoken aloud in English.
    4. //Thus, "StretchLeft" means stretching along the Y axis, and left-aligned on the X.
    5.  
    6. public static class Anchors
    7.   public static MinMax TopLeft = new MinMax(0, 1, 0, 1);
    8.   public static MinMax TopCenter = new MinMax(0.5f, 1, 0.5f, 1);
    9.   public static MinMax TopRight = new MinMax(1, 1, 1, 1);
    10.   public static MinMax TopStretch = new MinMax(0, 1, 1, 1);
    11.   public static MinMax MiddleLeft = new MinMax(0, 0.5f, 0, 0.5f);
    12.   public static MinMax TrueCenter = new MinMax(0.5f, 0.5f, 0.5f, 0.5f);
    13.   public static MinMax MiddleCenter = new MinMax(0.5f, 0.5f, 0.5f, 0.5f);
    14.   public static MinMax MiddleRight = new MinMax(1, 0.5f, 1, 0.5f);
    15.   public static MinMax MiddleStretch = new MinMax(0, 0.5f, 1, 0.5f);
    16.   public static MinMax BottomLeft = new MinMax(0, 0, 0, 0);
    17.   public static MinMax BottomCenter = new MinMax(0.5f, 0, 0.5f, 0);
    18.   public static MinMax BottomRight = new MinMax(1, 0, 1, 0);
    19.   public static MinMax BottomStretch = new MinMax(0, 0, 1, 0);
    20.   public static MinMax StretchLeft = new MinMax(0, 0, 0, 1);
    21.   public static MinMax StretchCenter = new MinMax(0.5f, 0, 0.5f, 1);
    22.   public static MinMax StretchRight = new MinMax(1, 0, 1, 1);
    23.   public static MinMax TrueStretch = new MinMax(0, 0, 1, 1);
    24.   public static MinMax StretchStretch = new MinMax(0, 0, 1, 1);
    25. //Cast everything under the sun into a RectTransform.  Note that I would not advise
    26. // actually doing this on something that isn't attached to a canvas.
    27. public static class Cast
    28.   public static RectTransform RT(this GameObject go)
    29.   public static RectTransform RT(this Transform t)
    30.   public static RectTransform RT(this Component c)
    31.  
    32. //Uncomment this line (or define it in one of your scripts) to get debug output when any function //that does work is called.
    33. //#define REKT_LOG_ACTIVE
    34.  
    35. //Used for the creation of this library, but may come in handy for others when attempting to understand
    36. // RectTransform. Outputs all the relevant aspects of a RectTransform to Debug.Log.
    37. public static void DebugOutput(this RectTransform RT)
    38.  
    39. //Acts as a wrapper to GetWorldCorners, that attempts to massage those points into a useable
    40. // Rect instead of a Vector3[].
    41. public static Rect GetWorldRect(this RectTransform RT)
    42.  
    43. /Helper functions for storing/saving the anchors as one, instead of dealing with both corners separately.
    44. // You can use the static variables in the Anchors class above
    45. public static MinMax GetAnchors(this RectTransform RT)
    46. public static void SetAnchors(this RectTransform RT, MinMax anchors)
    47.  
    48. //Casts the parent transform to RectTransform.
    49. public static RectTransform GetParent(this RectTransform RT)
    50.  
    51. //Gets/sets the width, height, or both.  Get is there for consistency, really.
    52. public static float GetWidth(this RectTransform RT)
    53. public static float GetHeight(this RectTransform RT)
    54. public static Vector2 GetSize(this RectTransform RT)
    55. public static void SetWidth(this RectTransform RT, float width)
    56. public static void SetHeight(this RectTransform RT, float height)
    57. public static void SetSize(this RectTransform RT, float width, float height)
    58. public static void SetSize(this RectTransform RT, Vector2 size)
    59.  
    60. //These four functions actually return the center of the edge mentioned, so
    61. // GetLeft gives you the center-left point, etc.
    62. public static Vector2 GetLeft(this RectTransform RT)
    63. public static Vector2 GetRight(this RectTransform RT)
    64. public static Vector2 GetTop(this RectTransform RT)
    65. public static Vector2 GetBottom(this RectTransform RT)
    66.  
    67. //Similar to setting the "Left" etc variables in the inspector.
    68. // Keep in mind that these functions all use standard directions when determining positioning; this means
    69. // that unlike the inspector, positive ALWAYS means to the right/top, and negative ALWAYS means to the left/
    70. // bottom.  If you want true inspector functionality, use Left() and so on, instead.
    71. public static void SetLeft(this RectTransform RT, float left)
    72. public static void SetRight(this RectTransform RT, float right)
    73. public static void SetTop(this RectTransform RT, float top)
    74. public static void SetBottom(this RectTransform RT, float bottom)
    75.  
    76. //Truly matches the functionality of the "Left" etc property in the inspector. This means that
    77. // Right(10) will actually move the right edge to 10 units from the LEFT of the parent's right
    78. // edge.  In other words, all coordinates are "inside": they measure distance from the parent's
    79. // edge to the inside of the parent.
    80. public static void Left(this RectTransform RT, float left)
    81. public static void Right(this RectTransform RT, float right)
    82. public static void Top(this RectTransform RT, float top)
    83. public static void Bottom(this RectTransform RT, float bottom)
    84.  
    85. //Repositions the requested edge relative to the passed anchor. This lets you set e.g.
    86. // the left edge relative to the parent's right edge, etc.
    87. public static void SetLeftFrom(this RectTransform RT, MinMax anchor, float left)
    88. public static void SetRightFrom(this RectTransform RT, MinMax anchor, float right)
    89. public static void SetTopFrom(this RectTransform RT, MinMax anchor, float top)
    90. public static void SetBottomFrom(this RectTransform RT, MinMax anchor, float bottom)
    91.  
    92. //Moves the edge to the requested position relative to the current position.
    93. public static void SetRelativeLeft(this RectTransform RT, float left)
    94. public static void SetRelativeRight(this RectTransform RT, float right)
    95. public static void SetRelativeTop(this RectTransform RT, float top)
    96. public static void SetRelativeBottom(this RectTransform RT, float bottom)
    97.  
    98. //Sets the position of the RectTransform relative to the parent's Left etc side,
    99. // regardless of current anchor setting.
    100. public static void MoveLeft(this RectTransform RT, float left = 0)
    101. public static void MoveRight(this RectTransform RT, float right = 0)
    102. public static void MoveTop(this RectTransform RT, float top = 0)
    103. public static void MoveBottom(this RectTransform RT, float bottom = 0)
    104.  
    105. //Moves the RectTransform to align the child left edge with the parent left edge, etc.
    106. public static void MoveLeftInside(this RectTransform RT, float left = 0)
    107. public static void MoveRightInside(this RectTransform RT, float right = 0)
    108. public static void MoveTopInside(this RectTransform RT, float top = 0)
    109. public static void MoveBottomInside(this RectTransform RT, float bottom = 0)
    110.  
    111. //Moves the RectTransform to align the child right edge with the parent left edge, etc
    112. public static void MoveLeftOutside(this RectTransform RT, float left = 0)
    113. public static void MoveRightOutside(this RectTransform RT, float right = 0)
    114. public static void MoveTopOutside(this RectTransform RT, float top = 0)
    115. public static void MoveBottomOutside(this RectTransform RT, float bottom = 0)
    116.  
    117. //Moves the RectTransform to the given point in parent space, considering (0, 0)
    118. // to be the parent's lower-left corner.
    119. public static void Move(this RectTransform RT, float x, float y)
    120. public static void Move(this RectTransform RT, Vector2 point)
    121.  
    122. //Wrappers for MoveLeftInside and MoveBottomInside, allowing you to call both at once.
    123. public static void MoveInside(this RectTransform RT, float x, float y)
    124. public static void MoveInside(this RectTransform RT, Vector2 point)
    125.  
    126. //Ditto for MoveLeftOutside and MoveBottomOutside.
    127. public static void MoveOutside(this RectTransform RT, float x, float y)
    128. public static void MoveOutside(this RectTransform RT, Vector2 point)
    129.  
    130. //Moves the RectTransform relative to an arbitrary anchor point.  This is effectively
    131. // like setting the anchor, then moving, then setting it back, but does so without
    132. // potentially getting in the way of anything else.
    133. public static void MoveFrom(this RectTransform RT, MinMax anchor, Vector2 point)
    134. public static void MoveFrom(this RectTransform RT, MinMax anchor, float x, float y)
    135.  
    136. //Translates a point on the parent's frame of reference, with (0, 0) being the parent's
    137. // lower-left hand corner, into the same point relative to the RectTransform's current
    138. // anchor.
    139. public static Vector2 ParentToChildSpace(this RectTransform RT, Vector2 point)
    140. public static Vector2 ParentToChildSpace(this RectTransform RT, float x, float y)
    141.  
    142. //Translates a point (presumably the RectTransform's anchoredPosition) into the same
    143. // point on the parent's frame of reference, with (0, 0) being the parent's lower-left
    144. // hand corner.
    145. public static Vector2 ChildToParentSpace(this RectTransform RT, float x, float y)
    146. public static Vector2 ChildToParentSpace(this RectTransform RT, Vector2 point)
    147.  
    148. //Normalizes a point associated with the parent object into "Anchor Space", which is
    149. // to say, (0, 0) represents the parent's lower-left-hand corner, and (1, 1) represents
    150. // the upper-right-hand.
    151. public static Vector2 ParentToAnchorSpace(this RectTransform RT, Vector2 point)
    152. public static Vector2 ParentToAnchorSpace(this RectTransform RT, float x, float y)
    153.  
    154. //Translates a normalized "Anchor Space" coordinate into a real point on the parent's
    155. // reference system.
    156. public static Vector2 AnchorToParentSpace(this RectTransform RT, float x, float y)
    157. public static Vector2 AnchorToParentSpace(this RectTransform RT, Vector2 point)
    158.  
    159. //Calculates the center of the rectangle that both anchors represent.  For most anchors this
    160. // will be the point that they sit on, but for stretch anchors it will be the center between them.
    161. public static Vector2 AnchorOrigin(this RectTransform RT)
    162. public static Vector2 AnchorOrigin(MinMax anchor)
    163.  
    164. //Calculates the anchor origin as above and puts it in parent space for you.
    165. public static Vector2 AnchorOriginParent(this RectTransform RT)
    166.  
    167. //Helper to get the top-most-level canvas that this RectTransform is a child of.
    168. public static Canvas GetRootCanvas(this RectTransform RT)
    169.  

    Comments and critique are welcome!
     
    Last edited: Sep 27, 2015
    SAOTA and EliasMasche like this.
  2. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Fixed a copy-paste typo. Updated OP link.
     
  3. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Fixed the setedge functions not working properly. Removed a debug output that was left in accidentally.
     
  4. LouisHong

    LouisHong

    Joined:
    Nov 11, 2014
    Posts:
    69
    Love the name. Got some gamer meme going on.
     
  5. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Haha, thanks. Soon as I thought of the name, I knew it was meant to be.

    Updated the file with the MIT license due to concerns brought up on /r/Unity2D.
     
  6. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Fixed the setedge functions so they work with all anchor types (oops! lol).
     
  7. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Changed the various Move functions so their names were less awkward and long. Added the new MoveOutside functions. Also added some fancy ASCII art to the script comments to explain the concepts a little more clearly.

    Updated the OP link and header list.
     
  8. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Added verbose logging and an extension method for gameobject, component, and transform.

    Verbose logging can now be turned on by calling RektTransform.RectTransformExtensions.Verbose = true, and turned off by setting that to false. Verbose logging simply logs each call made to the library; useful when you have multiple areas of code affecting an RT erratically.

    The new extension methods allow you to get the RectTransform of the above object types by calling RT():

    mySlider.gameObject.RT();
    mySlider.transform.RT();
    mySlider.RT();
     
  9. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Added the GetWorldRect function to the RectTransform extensions. This allows you to get a Rect representing the RectTransform's positioning in world space (screen space, usually). This is essentially just a wrapper for RectTransform.GetWorldCorners, which for some dumb reason returns a Vector3[].
     
  10. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    MASSIVE update, about doubled the lines of code to ~1000. Changes detailed in the OP.
     
  11. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Received some good input when I posted this on /r/Unity2D, which changes I'll incorporate after work. Any other critique?
     
  12. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Updated all the default anchors in the Anchors class to be readonly, and changed the debug output to use a Conditional instead of a static bool. Many thanks to /u/SIlentSin26 on /r/Unity2D for the pointers!
     
  13. ketura

    ketura

    Joined:
    Oct 2, 2013
    Posts:
    29
    Removed all the duplicate UIBehavior functions. Instead, UIBehavior has been included as one of the types that the Cast class extends with the RT() function, like so:

    myGameObject.RT();
    mySlider.RT();

    etc.