Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by YondernautsGames · Mar 18, 2015 at 05:46 PM · 2drotationuiimagelayout

Simple way to fit rotated UI element to parent

Hi there.

I'm working on a simple 2D interface for my game but there's one thing I haven't been able to sort without resorting to scripting. I'm looking to rotate an Image on a UI canvas and have it stretch to the size of the canvas. If I switch it to stretch on both axes, set the offsets to 0 and then Z rotation to 90, the aspect ratio is wrong.

In situations where the image or UI element does not depend on the parent, I can see how this makes sense, but to simply stretch to fit it's a pain.

To show what I mean:

alt text

I want my map to rotate based on the screen aspect ratio, but still stretch to the screen. The only way I can think to do this is to write a script that checks the size of the parent and uses that to override the size of the image. This would be a pain to get working reliably and so that it updates properly in the editor, etc.

Any ideas?

layout.jpg (115.9 kB)
Comment
Add comment · Show 8
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image YondernautsGames · Mar 19, 2015 at 12:21 PM 0
Share

It seems this is also the same for the autolayout components. Add a HorizontalLayoutGroup to the parent of the image and it will stretch before it rotates, so the end result looks like above and does not correctly constrain the image.

I've tried writing a script to do this by getting the sizeDelta of the parent and setting the the sizeDelta of the image to (parentDelta.y, parentDelta.x), but it seems to refuse to get the correct values. For some reason it's always a few pixels out so the image is close but not quite right.

Still need help here guys :)

avatar image YondernautsGames · Mar 19, 2015 at 12:51 PM 0
Share

Ok, completely stumped now. In scripts I don't seem to be able to find a consistent way to get the dimensions of the parent (I've tried adding a Debug.Log that prints out various properties of the parent RectTransform, but I just can't work out which values directly relate to its size. I know that the canvas size is 640x360, and with a parent panel that's stretched to fit, I cannot find a single property that contains those 2 numbers. $$anonymous$$y $$anonymous$$d has just gone numb :P).

I'm giving up and moving on for a while to clear my head, but I'm hoping I don't have to resort to 2 images - a portrait and landscape. That's a huge waste of memory.

avatar image Nymisu · Mar 19, 2015 at 01:39 PM 0
Share

Use layout elements, specifically "Layout Element" and "Content size fitter".

Layout groups technically don't do much without the "Layout element" in place, and can overflow without "Content size fitter" in place.

avatar image YondernautsGames · Mar 19, 2015 at 01:42 PM 0
Share

I've tried that, but all the layout elements seem to process scale before rotation, so the end result is stretched along the wrong axis. Thanks for the suggestion though, but I don't think I can get them to work unless I'm missing something.

avatar image Nymisu · Mar 19, 2015 at 01:59 PM 0
Share

You're rotating the wrong thing. You're not meant to rotate the content, but rather the panel which contains the content, the one with the content size fitter. $$anonymous$$ake an extra panel for it if you must :)

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by YondernautsGames · Mar 19, 2015 at 03:46 PM

Ok, this is the best solution I've come up with:

 using UnityEngine;
 using UnityEngine.UI;
 
 #if UNITY_EDITOR
 using UnityEditor;
 #endif
 
 [ExecuteInEditMode]
 [RequireComponent(typeof(RectTransform))]
 public class RotationFitter : MonoBehaviour, ILayoutSelfController {
 
     private RectTransform canvasTransform;
 
     void Awake() {
         canvasTransform = GetComponentInParent<Canvas>().gameObject.transform as RectTransform;
     }
 
     public void SetLayoutHorizontal() {
         RectTransform rt = transform as RectTransform;
         rt.sizeDelta = new Vector2(canvasTransform.sizeDelta.y, canvasTransform.sizeDelta.x);
     }
     public void SetLayoutVertical() {
         RectTransform rt = transform as RectTransform;
         rt.sizeDelta = new Vector2(canvasTransform.sizeDelta.y, canvasTransform.sizeDelta.x);
     }
     
     #if UNITY_EDITOR
     void Update () {
         if (canvasTransform == null)
             canvasTransform = GetComponentInParent<Canvas>().gameObject.transform as RectTransform;
 
         RectTransform rt = transform as RectTransform;
         rt.sizeDelta = new Vector2(canvasTransform.sizeDelta.y, canvasTransform.sizeDelta.x);
     }
     #endif
 }
 

The [ExecuteInEditMode] and the editor only Update() function are required to get it to respond automatically in the editor. I've also created it as a LayoutController, but I'm not sure whether this is the best way, or whether I even need to fill both layout functions. Good enough though. Unless someone comes up with better, I'ma shippin it :P

Just to clarify its usage, this needs to be attached to the Image UI Object (or whatever it is that needs scaling), and will scale it to match the canvas size.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image fermmmm · May 06, 2015 at 05:27 PM 0
Share

you are setting sizeDelta, that doesn't solve the issue from the source, other components that use sizeDelta will fail, like Aspect Ratio Fitter, this should be a bug report since there is no efficient way to solve the issue.

avatar image
3

Answer by Pavulon · Apr 07, 2017 at 02:59 PM

My solution for this problem was this script which I was attaching for every element which needs to be rotated by +/-90 degrees:

 using UnityEngine;
 
 [RequireComponent(typeof(RectTransform))]
 public class RotatedNodeFillParent : MonoBehaviour {
     private RectTransform rectTransform;
     
     void Awake() {
         rectTransform = GetComponent<RectTransform>();
         OnRectTransformDimensionsChange();
     }
 
     private void OnRectTransformDimensionsChange() {
         if (!rectTransform) {
             // OnRectTransformDimensionsChange might be called before Awake - let's ignore this call as we will update during Awake anyway.
             return;
         }
         if (!transform.parent) {
             return;
         }
         RectTransform parentTransform = transform.parent.GetComponent<RectTransform>();
         if (!parentTransform) {
             return;
         }
         float aspectRatio = parentTransform.rect.size.x / parentTransform.rect.size.y;
         float halfAspectRatio = aspectRatio / 2.0f;
         float halfAspectRatioInvert = (1.0f / aspectRatio) / 2.0f;
         rectTransform.anchorMin = new Vector2(0.5f - halfAspectRatioInvert, 0.5f - halfAspectRatio);
         rectTransform.anchorMax = new Vector2(0.5f + halfAspectRatioInvert, 0.5f + halfAspectRatio);
         rectTransform.anchoredPosition = Vector3.zero;
         rectTransform.offsetMin = Vector2.zero;
         rectTransform.offsetMax = Vector2.zero;
     }
 }
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Rotate world space UI element on Z axis towards gameobject. 0 Answers

Rotate world space UI element on Z axis towards gameobject. 1 Answer

How to lock element width or height in a vertical or horizontal layout? 1 Answer

Scrollable Achievement Tabs? 1 Answer

UI Elements Not Rendering Properly on Android 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges