Search code examples
unity3d-gui

Creating a flexible UI container for an image and a label


I have a list of friends which should be displayed in a scrollable list. Each friend have a profile image and a name associated to him, so each item in the list should display the image and the name.

The problem is that I cant figure out how to make a flexible container that contains both the image and the name label. I want to be able to change the width and height dynamically so that the image and the text will scale and move accordingly.

I am using Unity 5 and Unity UI.

I want to achieve the following for the container:

  • The width and height of the container should be flexible
  • The image is a child of the container and should be left aligned, the height should fill the container height and should keep its aspect ratio.
  • The name label is a child of the contianer and should be left aligned to the image with 15 px left padding. The width of the text should fill the rest of the space in the container.

Hope this is illustrated well in the following attached image:

enter image description here

I asked the same question here on Unity Answers, but no answers so far. Is it really possible that such a simple task is not doable in Unity UI without using code?


Solution

  • We never found a way to do this without code. I am very unsatisfied that such a simple task cannot be done in the current UI system. We did create the following layout script that does the trick (tanks to Angry Ant for helping us out). The script is attached to the text label:

    using UnityEngine;
    using UnityEngine.EventSystems;
    
    [RequireComponent (typeof (RectTransform))]
    public class IndentByHeightFitter : UIBehaviour,        UnityEngine.UI.ILayoutSelfController
    {
    public enum Edge
    {
        Left,
        Right
    }
    
    [SerializeField] Edge m_Edge = Edge.Left;
    [SerializeField] float border;
    
    public virtual void SetLayoutHorizontal ()
    {
        UpdateRect ();
    }
    
    
    public virtual void SetLayoutVertical() {}
    
    #if UNITY_EDITOR
    protected override void OnValidate ()
    {
        UpdateRect ();
    }
    #endif
    
    
    protected override void OnRectTransformDimensionsChange ()
    {
        UpdateRect ();
    }
    
    
    Vector2 GetParentSize ()
    {
        RectTransform parent = transform.parent as RectTransform;
    
        return parent == null ? Vector2.zero : parent.rect.size;
    }
    
    
    RectTransform.Edge IndentEdgeToRectEdge (Edge edge)
    {
        return edge == Edge.Left ? RectTransform.Edge.Left : RectTransform.Edge.Right;
    }
    
    
    void UpdateRect ()
    {
        RectTransform rect = (RectTransform)transform;
        Vector2 parentSize = GetParentSize ();
    
        rect.SetInsetAndSizeFromParentEdge (IndentEdgeToRectEdge (m_Edge), parentSize.y + border, parentSize.x - parentSize.y);
    }
    }