Search Unity

Content (falsely) determines container width. Please help me understand...

Discussion in 'UI Toolkit' started by carlosfritz, Apr 7, 2020.

  1. carlosfritz

    carlosfritz

    Joined:
    Feb 17, 2018
    Posts:
    32
    I am using Unity 2020.1.0b4 with UI Builder 0.10.2 and UIElements Runtime 0.0.4.

    screenshots.png

    The image shows two game-window-captures on top of each other. Clicking on the buttons at the bottom determines which VisualTreeAsset gets inserted above. When i click on the rightmost button, the containers width differs from when i click the two others. The only difference seems to be the labels texts. The strings revealed by the two left buttons have the same width and the resulting content widths are also equal.

    I have uploaded a demo-project.

    Btw, is my method of swapping content on click somehow funky? If so, how would you do it?

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UIElements;
    6. using Unity.UIElements.Runtime;
    7.  
    8. [RequireComponent(typeof(PanelRenderer))]
    9. [RequireComponent(typeof(UIElementsEventSystem))]
    10. public class UIManager : MonoBehaviour
    11. {
    12.   public VisualTreeAsset _presetsUxml;
    13.   public VisualTreeAsset _avatarsUxml;
    14.   public VisualTreeAsset _dialogUxml;
    15.  
    16.   PanelRenderer _panelRenderer;
    17.   List<UnityEngine.Object> _liveAssets;
    18.  
    19.   void Awake()
    20.   {
    21.     _panelRenderer = GetComponent<PanelRenderer>();
    22.     _liveAssets = new List<UnityEngine.Object>();
    23.   }
    24.  
    25.   void OnEnable()
    26.   {
    27.     _panelRenderer.postUxmlReload = BindScreen;
    28.   }
    29.  
    30.   void OnDisable()
    31.   {
    32.     _panelRenderer.postUxmlReload = null;
    33.   }
    34.  
    35.   IEnumerable<UnityEngine.Object> BindScreen()
    36.   {
    37.     var root = _panelRenderer.visualTree;
    38.  
    39.     var views = root.Q<VisualElement>("views");
    40.     var tabPresets = root.Q<Button>("tab-presets");
    41.     var tabAvatars = root.Q<Button>("tab-avatars");
    42.     var tabDialog = root.Q<Button>("tab-dialog");
    43.  
    44.     var presets = _presetsUxml.Instantiate();
    45.     var avatars = _avatarsUxml.Instantiate();
    46.     var dialog = _dialogUxml.Instantiate();
    47.  
    48.     views.Add(dialog);
    49.  
    50.     tabPresets.clicked += () => views.Replace(0, presets);//Replace is an extension
    51.     tabAvatars.clicked += () => views.Replace(0, avatars);
    52.     tabDialog.clicked += () => views.Replace(0, dialog);
    53.  
    54.     return _liveAssets;
    55.   }
    56. }
     
    Last edited: Apr 7, 2020
  2. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
    When no specific layout parameters are applied it is expected that children "drive" the size of their parent (in this case the text elements as you've correctly suggested).

    I think this issue is related your other question about the box model ; flex distribution will account for inherent sizes of elements.

    I'd again suggest using width: 50% if you want to divide the screen equally between two containers.

    As for this method of switching screens, I think it is fine. Using display:none may be a more efficient way to do it though since you are retaining the each root in memory. They may as well leave them in the hierarchy and turn them on/off. This will save some previous style/layout results.
     
  3. carlosfritz

    carlosfritz

    Joined:
    Feb 17, 2018
    Posts:
    32
    Thanks!
     
  4. carlosfritz

    carlosfritz

    Joined:
    Feb 17, 2018
    Posts:
    32
    For those who stumble upon this thread because of "display: none":
    Code (CSharp):
    1. using UnityEngine.UIElements;
    2.  
    3. public static class UIElementsExtensions
    4. {
    5.   public static void Hide(this VisualElement element)
    6.   {
    7.     element.style.display = DisplayStyle.None;
    8.   }
    9.  
    10.   public static void Show(this VisualElement element)
    11.   {
    12.     element.style.display = DisplayStyle.Flex;
    13.   }
    14. }