Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Better UI

Discussion in 'Assets and Asset Store' started by Hosnkobf, Jan 30, 2017.

  1. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Hi @MaxGuernseyIII
    What you are asking for is not possible with the current version of Better UI but I already planned it as a feature for the next version. I plan to have a screen configuration option for individual tags which you can set via code. The system already allows mixing different kinds of options in one screen cofiguration, so, everything you are asking for will be possible.

    I am pretty busy right now but I hope I can make something within the next month. I will send you a Beta as soon as I have something :)
     
  2. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    That sounds great. Right now, I have am auto-re-parenting component I've used as a shim. So I just have two parallel groups of invisible objects that represent a layout and then switch the parents back and forth.

    Would love to replace it with something a little cleaner.

    Looking forward to it.
     
  3. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Better UI is on sale now: 50% off!

    I planned to make an update before the sale but there is another game project which needs my attention now.
    However, the update will come. I don't want to promise too much but it is more than likely that it will be released within this year.
     
    Last edited: Aug 31, 2020
  4. Grumpy-Dot

    Grumpy-Dot

    Joined:
    Feb 29, 2016
    Posts:
    86
    @Hosnkobf BetterUI_TextMeshPro package is a bit outdated and has an error if one is using the latest TextMeshPro version (3.0.1). TMP_UiEditorPanel class is now missing and probably needs to be replaced with TMP_BaseEditorPanel in the BetterTextMeshProUGUIEditor script.

    Also, please fix the inconsistent line endings in HueSaturationBrightness.shader and ColorOverlay.shader. Thanks!
     
  5. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Hi @Grumpy-Dot,
    Thanks for pointing out. I have added your findings to my task list and will have it fixed in the next version.
     
  6. WuchiOnline

    WuchiOnline

    Joined:
    Apr 5, 2018
    Posts:
    7
    I'm also experiencing this exact error that @Grumpy-Dot mentioned regarding TMP_UiEditorPanel and TMP_BaseEditorPanel. What is the best workaround for this in the meantime? When I replace TMPro.EditorUtilities.TMP_UiEditorPanel with TMPro.EditorUtilities.TMP_BaseEditorPanel, it says I should implement 3 more methods from the abstract class. Should I just implement those as empty methods or is there a better approach? @Hosnkobf
     
  7. WuchiOnline

    WuchiOnline

    Joined:
    Apr 5, 2018
    Posts:
    7
    Quick update: I tried to create a new TextMeshPro Text (UI) component, right clicked it, chose Make Better, and I got thrown an exception because of the empty implemented IsMixSelectionTypes() method that I mentioned above. And I'm not sure if I'm missing something, but the new Better TMP Text component does not have a text input field.
     
  8. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    I took a look.
    Here is the quick fix for TMP 3.0.1:

    in
    Assets/TheraBytes/BetterUI_TextMeshPro/Editor/Scripts/BetterTextMeshProUGUIEditor.cs
    change line 13
    from:
    Code (csharp):
    1.     public class BetterTextMeshProUGUIEditor : TMPro.EditorUtilities.TMP_UiEditorPanel
    to:
    Code (csharp):
    1.     public class BetterTextMeshProUGUIEditor : TMPro.EditorUtilities.TMP_EditorPanel
     
    Grumpy-Dot likes this.
  9. Mariusz_H

    Mariusz_H

    Joined:
    May 4, 2018
    Posts:
    17
    Are there plans to add Style Sheets to the asset? Or at last make Better UI compatible with assets like Easy UI Styles ( https://assetstore.unity.com/packages/tools/utilities/easy-ui-styles-73899 ) ?


    Also, can you clean your code in next update? I really hate assets that pollute my console and I get following warnings with BetterUI:

    Code (CSharp):
    1. Assets\Plugins\TheraBytes\BetterUI\Runtime\Scripts\BetterUiLayout\TransformScaler.cs(27,14): warning CS0114: 'TransformScaler.OnDisable()' hides inherited member 'UIBehaviour.OnDisable()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
    Code (CSharp):
    1. Assets\Plugins\TheraBytes\BetterUI\Runtime\Scripts\BetterUiLayout\LocationAnimations.cs(120,16): warning CS0649: Field 'LocationAnimations.startLocation' is never assigned to, and will always have its default value null
    Code (CSharp):
    1. Assets\Plugins\TheraBytes\BetterUI\Runtime\Scripts\BetterUiLayout\LocationAnimations.cs(126,32): warning CS0649: Field 'LocationAnimations.actionOnInit' is never assigned to, and will always have its default value null
     
  10. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Hi @Mariusz_H

    I was actually already thinking about a skinning system for Better UI. But since that is a larger change and has lots of implications it will not be part of the version 2 cycle.

    Supporting third party assets is not so easy as well. In the next version you will be able to change colors and sprites based on the screen configurations. This would clash with third party assets. One of them would override the other and it is not clear, which of them.
    But most of the Easy UI Style settings should also work with Better UI Controls. Did you test it?
    If something doesn't work, can you tell me what is working and what is not?

    Sorry for the inconvenience. I will double-check the console before releasing the next version.
     
  11. Mariusz_H

    Mariusz_H

    Joined:
    May 4, 2018
    Posts:
    17
    Integrating Better UI with other libraries requires a lot of programming yoga so skinnig system would be a great feature for Better UI :) Even simple thing like reskinnig objects by dropping on them scriptable objects with skin definitions would greatly improve workflow of anyone working with UI.

    Thank you!
     
  12. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    As far as I could see from the screenshots, Easy UI Styles can apply certain defined values to Images, Buttons, Labels...
    Since BetterUI is actually extending these objects, it is likely that Easy UI Styles can also apply the styles to Better UI components (e.g. settings for an Image can probably also be applied to Better Image).

    Only values which are also driven through Better UI can become tricky. Here you will probably need to tweak the script execution order (Resolution Monitor and Better UI components should be early in such a scenario, so that Better UI applies first and then it is overridden by the styling library).

    Yes, but I want to do it right and working in any scenario. Therefore, I first need to think about the best possible integration and also think about possible problems with responsive designs. Maybe the changes would break projects with previous versions of Better UI, so I have to be very careful.
    So, this will not be integrated in the next version. But I definitely want to implement it for Better UI 3.
     
    Last edited: Sep 28, 2020
  13. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Here's a bizarre problem. When I build for WebGL on Unity 2020.1, it appears to work fine...until I host the result in an iframe. Then it always picks the landscape layout regardless of the shape of the frame or the window. Has anybody else experienced this?
     
  14. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    can you print or log the
    Screen.width
    and
    Screen.height
    for the non-working version and post the result here?
     
  15. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Screen.width=1620 Screen.height=2880
     
  16. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    If I set the browser dimensions to be the same and go directly to the page, it works fine...
     
  17. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    So, when you load it that way, some script or other ends up setting the dimensions of the canvas. I'm guessing it does it in a way that causes the screen to look like it's in portrait when one of those properties are set and doesn't cause whatever event you're monitoring to fire when the other dimension is set.
     
  18. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
  19. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Does Better Axis Aligned Layout Group have an equivalent to the "Reverse Arrangement" setting on the Vertical Layout Group?
     
  20. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    I had to add it...

    BetterHorizontalOrVerticalLayoutGroupEditor:98
    Code (CSharp):
    1.  
    2.             var oriantation = findProp("orientation", "Orientation");
    3.             var reverseArrangement = findProp("m_ReverseArrangement", "ReverseArrangement");
    4.  
    5.             var childAlignment = findProp("m_ChildAlignment", "ChildAlignment");
    6.          
    7.             var childControlSizeWidth = findProp("m_ChildControlWidth", "ChildControlWidth");
    8.             var childControlSizeHeight = findProp("m_ChildControlHeight", "ChildControlHeight");
    9.  
    10.             var childForceExpandWidth = findProp("m_ChildForceExpandWidth", "ChildForceExpandWidth");
    11.             var childForceExpandHeight = findProp("m_ChildForceExpandHeight", "ChildForceExpandHeight");
    12.  
    13.             if(parent != null)
    14.             {
    15.                 EditorGUILayout.BeginVertical("box");
    16.             }
    17.  
    18.             if (oriantation != null)
    19.             {
    20.                 EditorGUILayout.PropertyField(oriantation);
    21.             }
    22.  
    23.             EditorGUILayout.PropertyField(reverseArrangement, true);
    24.             EditorGUILayout.PropertyField(childAlignment, true);
    25.  
    BetterAxisAlignedLayoutGroup.cs:16
    Code (CSharp):
    1.  
    2.         [Serializable]
    3.         public class Settings : IScreenConfigConnection
    4.         {
    5.             public TextAnchor ChildAlignment;
    6.             public bool ChildForceExpandHeight = true;
    7.             public bool ChildForceExpandWidth = true;
    8.             public bool ChildControlWidth = true;
    9.             public bool ChildControlHeight = true;
    10.             public Axis Orientation;
    11.             public bool ReverseArrangement = false;
    12.  
    13.             [SerializeField]
    14.             string screenConfigName;
    15.             public string ScreenConfigName { get { return screenConfigName; } set { screenConfigName = value; } }
    16.  
    17.  
    18.             public Settings(TextAnchor childAlignment, bool expandWidth, bool expandHeight, Axis orientation, bool reverseArrangement)
    19.             {
    20.                 this.ChildAlignment = childAlignment;
    21.                 this.ChildForceExpandWidth = expandWidth;
    22.                 this.ChildForceExpandHeight = expandHeight;
    23.                 this.Orientation = orientation;
    24.                 this.ReverseArrangement = reverseArrangement;
    25.             }
    26.         }
    27.  
    BetterAxisAlignedLayoutGroup.cs:122
    Code (CSharp):
    1.  
    2. settingsFallback = new Settings(this.childAlignment, this.childForceExpandWidth, this.childForceExpandHeight, this.orientation, this.reverseArrangement)
     
  21. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Hi @MaxGuernseyIII
    Nice that you could implement it yourself :)

    This setting seems to be relatively new. I will add it to Better UI in the next version. Thanks for your work already :)

    PS: for any new features in UI components - except for horizontal / vertical layout groups - you can find and change the settings if you view the Better version of that UI component in the Debug view of the inspector.
     
  22. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Yes. The code is pretty easy to modify and I've had good luck with the "fix it myself and give you the fix" path, before.
     
  23. realragnvaldr

    realragnvaldr

    Joined:
    Jul 21, 2019
    Posts:
    40
    Hi!

    Bought the asset yesterday to speed up my implementation of a "Growing input field" for a chat function. I was happy to see how smoothly that went using your tutorial, but now I ran into a minor issue: misalignment of the caret as well as selection highlighting when touching the contents of the input field.

    Here's an example of what i mean:



    What i did was:
    - type "test text" in my input field
    - double "click" (touch) on "text"

    When I press "cut", it cuts the part in blue - so the blue is fine, but the green is misaligned. Also, if i "single click" the text somewhere to move the caret, it ends up to a place to the right of where i press.

    Any clue what this can be? I'm using more or less the same setup as you describe in your "Growing input field" video and can provide more details if necessary.
     
  24. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Hi @realragnvaldr
    Although your screenshot looks pretty much like native android UI, I guess you have built everything yourself using UGUI.
    However, I am not sure how you implemented the text selection UI. Did you do this yourself? And which text solution do you use? TextMesh Pro?
    I cannot really help without implementation details. All I can tell is that this is not directly related to Better UI. There is somewhere else some code which does wrong positioning calculations.
     
  25. seven_

    seven_

    Joined:
    Sep 30, 2014
    Posts:
    42
    Hi, is there a way to ensure several BetterText components use the very same font size? Use case: Several text elements belonging to a common UI should have to very same font size, generally that smallest calculated font size of an individual text element (using Stay in Bounds). If I read over the solution for this, please just point me to some documentation. Thanks!
     
  26. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Hi @seven_
    Right now there is no greater manager monitoring several objects to keep them in the same style. Every ui element is managing itself only (except for layout elements). So, I am sorry that Better UI does not offer what you are looking for.

    I have ideas for a skinning system which could contain such advanced features, but this would be a very complex feature which will not come in the near future.
     
  27. seven_

    seven_

    Joined:
    Sep 30, 2014
    Posts:
    42
    Okay, thanks. So, this is the skinning issue you talked about previously... I think I will use nonbreakable spaces in an extra line in all text elements belonging together, letting the layout system assuming the same width of all texts...
     
  28. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    You can also try to use the "Sizer Only" setting. This would let all texts have the same size (if the same values are entered). However, the layout could look broken if the text is too long (overflows). So, if you do that, you should carefully check all possible texts with all supported resolutions.
     
  29. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    There are two things I would like to announce:

    First Thing:
    Better UI is on Sale (50% off) since yesterday until January 7th 2021.

    Second Thing:
    Better UI version 2.3 has been submitted and will be released within the next days.

    New Features
    • Location Animations: "Use Relative Locations" toggle allows to define locations relative to the location they have when loaded.
      This allows to design animations regardless of their final positions (and reuse them: like several of the same button at different places)
    • Screen Configs: Users can now define custom Tags for checking screen configurations. These can be triggered through code like this:
      Code (CSharp):
      1.     TheraBytes.BetterUi.ResolutionMonitor.AddScreenTag("Accessibility_Mode");
      2.     TheraBytes.BetterUi.ResolutionMonitor.RemoveScreenTag("Accessibility_Mode");
      3.     TheraBytes.BetterUi.ResolutionMonitor.ClearScreenTags();

    • BetterImage / BetterRawImage: Some settings (Better Image: Sprite + Color options / Better Raw Image: Texture + Color options + UV Rect) can now be changed per screen configuration.
      This can be useful if you want to display different images per screen configuration tag (like the logo of the current OS) or if you want to use different gradient directions per orientation.
    • Transitions: The new Transition type "Custom Callback" allows to call a method or change the value of a variable when the transition state changes.
    • Grayscale Material now has an "Amount" property which allows to interpolate between color and grayscale.
    • AxisAlignedLayoutGroup: Added Support for "Use Child Scale" (Unity 2019+) and "Reverse Arrangement" (Unity 2020+)
    • BetterScrollRect: There are now sizers for horizontal / vertical scrollbar spacing (if visibility is set to AutoHideAndExpandViewport)
    Small Changes
    • Suppressed irrelevant warnings in the console
    • Added Multi-Component-Editing Capabilities to Better Components (except Location Animations)
      Note: this may not work as expected on all components, like TextMesh Pro (only showing the Better UI part)
    • Unscaled time is now used everywhere in Better UI (UI should usually not be affected by time scale)
    Fixes
    • Fixed Update logic when Better UI elements are disabled
    • Fixed Fallback Screen Config changes (values reset previously)
    • Fixed Anchor Override for Canvases with Camera
    • Fixed DPI Override list: possible to add / remove entries again
    • Fixed NaN Bug in Anchor Override (was causing disappearing elements)

    • If you see a compile error, delete the editor file
      TheraBytes/BetterUI/Editor/Scripts/BetterScrollRect
      .
    • The spacing for existing BetterScrollRects might be overwritten after importing the Better UI v2.3.
      Please check your BetterScrollRects before importing and assign the right values again after import.
    • Any Better(Raw)Images with a Grayscale material assigned will not appear grayscale after import.
      Change the Material to something else and back to Grayscale to fix it.
      If this does not fix it, delete
      TheraBytes/Resources/Materials
      and try the material change again.
    • Unity 5.4 is not officially supported anymore. The minimum Unity version for Better UI is 5.5 now.
      Most features will also work with Unity 5.4 though. If you are upgrading a Unity 5.4 project, do not import the shader files of Better UI 2.3.

    Please note that the online documentation is not up to date yet.

    Thanks to all your feedback.
    Especially @MaxGuernseyIII and @Grumpy-Dot for their great ideas and findings.
     
    Last edited: Dec 16, 2020
    nemeth-regime and Grumpy-Dot like this.
  30. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    The Documentation is updated to version 2.3 now. I also enabled SSH for the documentation now, so that the connection is secure.

    You may need to clear your browser cache to see the new documentation.
    Alternatively, you can use this link: https://documentation.therabytes.de/better-ui_2.3
     
    Last edited: Dec 21, 2020
  31. nemeth-regime

    nemeth-regime

    Joined:
    Feb 13, 2017
    Posts:
    38
    @Hosnkobf
    Feature request...
    Reverse order of layout groups.
     
  32. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    @millar5001
    There is a "Reverse Arrangement" option for Better Axis Aligned Layout Groups. This feature is only available for pojects based on Unity 2020 or later since it triggers the reverse arrangement logic that was introduced with Unity 2020.1.

    If you are talking about a different feature you are looking for, please give me more details.
     
  33. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    There is a bug in Location Animations where animations which have "Use Relative Locations" enabled move unexpectedly when "From" or "To" is set to "[ Any Location ]".

    To fix this, open
    \Assets\TheraBytes\BetterUI\Runtime\Scripts\BetterUiLayout\LocationAnimations.cs
    and replace line 286:
    Code (CSharp):
    1. /* original line (which should be replaced):
    2.             RectTransformData result = (useRelativeLocations)
    3. */
    4.  
    5. // replacement line:
    6.             RectTransformData result = (useRelativeLocations && loc != null)
    7.  
    Thanks for reporting @Grumpy-Dot.
    This fix will be integrated in the next version.
     
    Grumpy-Dot likes this.
  34. fkorsa

    fkorsa

    Joined:
    Dec 23, 2018
    Posts:
    9
    @Hosnkobf
    Hi! Thanks for a great asset!

    I have noticed that the way you retrieve the screen's DPI suffers from Unity's bug on WebGL, since you merely use Screen.dpi (which always returns 96 on webgl, even on devices which have a different DPI).

    One can get the actual dpi through a javascript plugin. It's actually pretty straight-foward, here is some example code (which I use myself in production already):

    CrossPlatformScreenDPI.cs:
    Code (CSharp):
    1.  
    2. using System.Runtime.InteropServices;
    3. using UnityEngine;
    4.  
    5. public class CrossPlatformScreenDPI : MonoBehaviour
    6. {
    7.     public bool emulateResolution = false;
    8.     public float emulatedDPI = 96.0f;
    9.  
    10. #if UNITY_WEBGL
    11.     [DllImport("__Internal")]
    12.     private static extern double GetDPI();
    13. #endif
    14.  
    15.     private float dpi = 96.0f;
    16.     private bool isInitialized = false;
    17.  
    18.     private void Initialize()
    19.     {
    20. #if UNITY_WEBGL && !UNITY_EDITOR
    21.         double dpiFromJavascript = GetDPI();
    22.         Debug.Log("dpi from javascript: " + dpiFromJavascript);
    23.         dpi = (float) dpiFromJavascript * 96.0f;
    24. #else
    25.         dpi = Screen.dpi;
    26. #endif
    27. #if UNITY_EDITOR
    28.         if (emulateResolution)
    29.         {
    30.             dpi = emulatedDPI;
    31.         }
    32. #endif
    33.         Debug.Log("resulting dpi: " + dpi);
    34.         isInitialized = true;
    35.     }
    36.  
    37.     public float GetScreenDPI()
    38.     {
    39.         if (!isInitialized)
    40.         {
    41.             Initialize();
    42.         }
    43.         return dpi;
    44.     }
    45. }
    46.  
    WebGLDPI.jslib:
    Code (JavaScript):
    1. mergeInto(LibraryManager.library, {
    2.  
    3.     GetDPI: function ()
    4.     {
    5.         return window.devicePixelRatio;
    6.     },
    7.  
    8. });
    Note that the C# script I pasted above also has the perk of letting me emulate the DPI in the editor, to test the layout of a different DPI without having to send a build to my phone for example (which has a very different DPI than my computer).
     
    Hosnkobf likes this.
  35. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    @fkorsa
    Thank you very much for your contribution! I was not aware that this is a Unity bug that can be fixed by hand. I really appreciate that you share your knowledge and I will take a closer look (and probably integrate something similar) before releasing the next version :)


    @all-who-bought-better-ui-in-december
    I always like to help people with their projects by providing my code (Better UI) or knowledge, but I am also glad that other people like to help as well with totally different expertise. So does the company I am working for. That is why we donated the income of Better UI's december sales to medecins sans frontieres. Thanks for helping us helping these helping hands.
     
    fkorsa and Grumpy-Dot like this.
  36. fkorsa

    fkorsa

    Joined:
    Dec 23, 2018
    Posts:
    9
    Woah, that's awesome!

    On another topic, I have some bug reports to make.

    1. The "Dpi" impact mode for size modifiers is surprisingly impacted by the zoom factor of the game view. For example, if I drive the size of my text field using the "Dpi" impact mode, then the size of the text changes when I zoom in or out in the game view. I would not expect that to happen, instead I would expect the dpi to match my machine's dpi.
    2. In Unity 2020.1.17f1, I have some null reference exceptions whenever I create a Better Locator. They are easily solved by initializing those fields (BetterLocator.cs):
    [SerializeField]
    RectTransformData transformFallback = new RectTransformData();

    [SerializeField]
    RectTransformDataConfigCollection transformConfigs = new RectTransformDataConfigCollection();

    And also here (RectTransformData.cs):
    [SerializeField]
    string screenConfigName = "";

    Still, great asset! Can't wait to see further development on this. And thanks again for taking the time and energy to share your code with the community.
     
  37. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    That is actually a feature. The zoom factor simulates a resolution but with different actual resolution. So, the dpi is actually also different in simulation space. But I didn't implement this because of this weired logic. I implemented it to preview dpi-sizing in the editor to get a feeling about it.
    Is this problematic for you? If yes, please explain me why so I can find the best solution.

    I couldn't reproduce this. "OnValidate()" should actually initialize the component if uninitialized... It works for me without Exceptions when rightclicking the RectTransform and select "Add Better Locator" as well as if I add a Better Locator via "Add Component".
    Please answer me some questions:
    1. Are you using a third party serializer in your project (like Odin)?
    2. Are you adding the Better Locator during runtime?
    3. Can you provide steps to reproduce the bug?
    Thanks :)
     
  38. floriankorsakissok

    floriankorsakissok

    Joined:
    Jul 19, 2017
    Posts:
    20
    Since then, I have figured that I actually will never need the 'dpi' impact mode in my project. So it's not a personal matter anymore :)
    But in general, I think I disagree with the usage of the game view's scale factor as a way to preview layout changes due to dpi. The game view's scale factor has a purpose on its own, which is to zoom in or out somewhere. Adding another effect to it is a bit annoying: then if I only want to zoom in or out, I will be annoyed by my layout changing, and if I only want to preview dpi changes, I will be annoyed by the view zooming in or out.
    I think what I would actually like ideally, is a dedicated way to simulate a different dpi than the current machine's. Like a list of dpis similar to the list of resolutions in the resolution picker, or a dpi slider in the resolution picker.
    I have actually already done that in my project, it was quite easy to do. I can share the code if you're interested, just tell me if that's the case.

    I'm not using a third party serializer.
    I am not adding the better locator during runtime - it's within the editor. I'm adding a component through the inspector.
    The steps are really just that, click 'Add Component' on a game object with a rect transform, choose better locator. Then the error messages pop in the editor log.
    Since you do not reproduce, I guess there must be something particular about my configuration. But I have no idea what, sorry. What I can say is that for some reason, BetterLocator::OnEnable is called before BetterLocator::OnValidate in my particular configuration, and thus transformConfigs is not yet initialized.
    The solution I posted above, with
    RectTransformDataConfigCollection transformConfigs = new RectTransformDataConfigCollection();
    ended up not being satisfactory, because whenever I would create a new better locator, the previous transform would be lost. So instead, I modified BetterLocator::OnEnable so that it would not execute its body when running inside editor code (i.e. UNITY_EDITOR is defined and Application.isPlaying is false). That solved it more gracefully.
    That was just FYI, but feel free to disregard this bug report, since you do not reproduce and nobody else reported it yet. I have a workaround so it's not a big deal at all.

    Thanks for your responsiveness!
     
  39. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Let me explain why I think this behaviour is actually good:
    When you scale by DPI you want your UI Element always have the same physical size. Check out the Example Scene "Layout" tab. there is a ruler which will always display 1 inch and 1 cm sections in the middle of the screen (like a ruler). These will be 1 inch / 1 cm wide on every screen. When you zoom the size of the ruler remains the same physical size as it would on any screen.


    I could reproduce it now: It happens for me when you add a Better Locator while in play mode. Usually you don't do that since the added component would be removed again as soon as you exit play mode...
    But it is still okay to do that if you quickly want to test something or want to copy a component with in-game locations...

    EDIT (previously here was a non-working code snippet):

    I fixed it for the next version. I guess your fix also does the job well enough.
     
    Last edited: Jan 14, 2021
  40. fkorsa

    fkorsa

    Joined:
    Dec 23, 2018
    Posts:
    9
    Fair enough :)

    Cool, thanks! Although in my case, play mode was not on, sorry.

    Am I the only one for which making a vertical or horizontal layout better loses the state of the checkboxes? I.e. when I make a vertical layout which has any of the "Child Control Size" or "Child Force Expand" checkboxes ticked, they get un-ticked in the better version.
     
  41. fkorsa

    fkorsa

    Joined:
    Dec 23, 2018
    Posts:
    9
    Same for the layout elements actually. Any values are lost when making them better, they just end up with all checkboxes unticked.
     
  42. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Hust realized that I tried reproduction on a Unity 2020.1.17f1 test project with an outdated version of Better UI. I am so sorry for this mistake. I now could reproduce your case and fixed it.
    here is the fix:
    1. In RectTransformData.cs remove the last line of
    GetHashCode()
    (line 261). Don't forget to add a semicolon at the last character of that method.

    2. Replace the content of BetterLocator.cs with this:
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using UnityEngine;
    6.  
    7. #pragma warning disable 0649 // disable "never assigned" warnings
    8.  
    9. namespace TheraBytes.BetterUi
    10. {
    11. #if UNITY_2018_3_OR_NEWER
    12.     [ExecuteAlways]
    13. #else
    14.     [ExecuteInEditMode]
    15. #endif
    16.     [DisallowMultipleComponent]
    17.     [RequireComponent(typeof(RectTransform))]
    18.     [AddComponentMenu("Better UI/Layout/Better Locator", 30)]
    19.     public class BetterLocator : MonoBehaviour, IResolutionDependency
    20.     {
    21.  
    22.         [Serializable]
    23.         public class RectTransformDataConfigCollection : SizeConfigCollection<RectTransformData> { }
    24.  
    25.         [SerializeField]
    26.         RectTransformData transformFallback;
    27.  
    28.         [SerializeField]
    29.         RectTransformDataConfigCollection transformConfigs = new RectTransformDataConfigCollection();
    30.  
    31.         public RectTransformData CurrentTransformData { get { return transformConfigs.GetCurrentItem(transformFallback); } }
    32.  
    33.         RectTransform rectTransform { get { return this.transform as RectTransform; } }
    34.  
    35.         void OnEnable()
    36.         {
    37.             if (transformFallback == null)
    38.             {
    39.                 InitTransformFallback();
    40.             }
    41.  
    42.             CurrentTransformData.PushToTransform(rectTransform);
    43.         }
    44.  
    45.         public void OnResolutionChanged()
    46.         {
    47.             CurrentTransformData.PushToTransform(rectTransform);
    48.         }
    49.  
    50. #if UNITY_EDITOR
    51.         public void OnValidate()
    52.         {
    53.             bool isUnInitialized = transformFallback == null
    54.                 || (transformConfigs.Items.Count == 0
    55.                 && transformFallback.Scale == Vector3.zero
    56.                 && transformFallback.Rotation.eulerAngles == Vector3.zero
    57.                 && transformFallback.AnchoredPosition == Vector2.zero
    58.                 && transformFallback.AnchorMin == Vector2.zero
    59.                 && transformFallback.AnchorMax == Vector2.zero
    60.                 && transformFallback.Pivot == Vector2.zero
    61.                 && transformFallback.SizeDelta == Vector2.zero
    62.                 && transformFallback.LocalPosition == Vector3.zero);
    63.  
    64.             if (isUnInitialized)
    65.             {
    66.                 InitTransformFallback();
    67.             }
    68.         }
    69. #endif
    70.  
    71.         void InitTransformFallback()
    72.         {
    73.             if (transformFallback == null)
    74.             {
    75.                 transformFallback = new RectTransformData();
    76.             }
    77.  
    78.             transformFallback.PullFromTransform(rectTransform);
    79.         }
    80.     }
    81. }
    82.  

    For me the checkboxes are the same as before. Do you see any errors regarding classes with the same name in the console? When you make it better, does it become an AxisAlignedLayoutGroup?

    I could reproduce this! Thanks for the report, I will work on a solution soon.

    Edit:
    Seems like I simply forgot to implement the Make-Better-Logic of Layout Elements.
    Here is the implementation:
    In BetterLayoutElementEditor.cs replace the method
    MakeBetter()
    with this:
    Code (CSharp):
    1.         [MenuItem("CONTEXT/LayoutElement/♠ Make Better")]
    2.         public static void MakeBetter(MenuCommand command)
    3.         {
    4.             LayoutElement layout = command.context as LayoutElement;
    5.             var ignore = layout.ignoreLayout;
    6.             var minWidth = layout.minWidth;
    7.             var minHeight = layout.minHeight;
    8.             var prefWidth = layout.preferredWidth;
    9.             var prefHeight = layout.preferredHeight;
    10.             var flexWidth = layout.flexibleWidth;
    11.             var flexHeight = layout.flexibleHeight;
    12.  
    13.             var newLayout = Betterizer.MakeBetter<LayoutElement, BetterLayoutElement>(layout) as BetterLayoutElement;
    14.             if(newLayout != null)
    15.             {
    16.                 newLayout.CurrentSettings.IgnoreLayout = ignore;
    17.  
    18.                 newLayout.CurrentSettings.MinWidthEnabled = (minWidth >= 0);
    19.                 newLayout.CurrentSettings.MinHeightEnabled = (minHeight >= 0);
    20.  
    21.                 newLayout.CurrentSettings.PreferredWidthEnabled = (prefWidth >= 0);
    22.                 newLayout.CurrentSettings.PreferredHeightEnabled = (prefHeight >= 0);
    23.  
    24.                 newLayout.CurrentSettings.FlexibleWidthEnabled = (flexWidth >= 0);
    25.                 newLayout.CurrentSettings.FlexibleHeightEnabled = (flexHeight >= 0);
    26.  
    27.  
    28.                 newLayout.MinHeightSizer.SetSize(newLayout, minHeight);
    29.                 newLayout.MinWidthSizer.SetSize(newLayout, minWidth);
    30.  
    31.                 newLayout.PreferredWidthSizer.SetSize(newLayout, prefWidth);
    32.                 newLayout.PreferredHeightSizer.SetSize(newLayout, prefHeight);
    33.  
    34.                 newLayout.CurrentSettings.FlexibleWidth = flexWidth;
    35.                 newLayout.CurrentSettings.FlexibleHeight = flexHeight;
    36.             }
    37.         }
     
    Last edited: Jan 18, 2021
  43. fkorsa

    fkorsa

    Joined:
    Dec 23, 2018
    Posts:
    9
    No worries! Thanks a lot for the fixes, it's appreciated :)

    I do not see any errors regarding classes with the same name, no. It does become a Better Axis Aligned Layout Group after making it better.
    I have since then noticed that it's not always that I lose the checkboxes' state. It's actually rather mitigated, sometimes I lose them, sometimes I don't. I could not figure out exactly what are the conditions to make it 100% reproducible. I suspect it has to do with working in nested prefabs though. But I can imagine that this is not enough information to fix the issue ^^ Sorry. If I find out what the conditions are, I'll be sure to notify you.

    Thanks again for an awesome support!
     
    Hosnkobf likes this.
  44. fkorsa

    fkorsa

    Joined:
    Dec 23, 2018
    Posts:
    9
    I had an issue where ScriptableObjectInstantiator.Initialize() was called too early during Unity's startup, which caused the resource files (ResolutionMonitor.asset and Material.asset) to be reset to their default state.
    The scenario is a bit unconventional, which is likely why it was never reported before. My CI setup uses Unity in batch mode to start a build. It runs something like
    Code (JavaScript):
    1. Unity.exe [...] -executeMethod MyStaticClass.BuildAndroid
    , so a custom-made script to make a build (otherwise there is no way of starting an android build from the command-line).
    However, when Unity is started that way, ScriptableObjectInstantiator.Initialize() will be called at a time where the Resources folder are not yet parsed, which means that var obj = Resources.Load(resourceFilePath); in SingletonScriptableObject will return null. And thus a new instance of that resource will be created & saved in the project.
    That is of course quite problematic, since my build will thus lose all the defined settings for BetterUI.

    I did not find an elegant way of resolving this. I resorted to simply comment out the Initialize(); call in the ScriptableObjectInstantiator contructor for now.

    Hopefully it will help others at least, but I think it would be nice to have a proper fix in the BetterUI releases.
     
  45. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Thank you so much for sharing your findings. This bug (with less information) was reported to me before and I even experienced it a few times also in Unity Editor itself. But since it happened only sometimes I was not able to guess what was the cause.

    With your report now I probably have a way to reproduce it and a place to investigate. This is super helpful. Thank you!

    I will definitely look into it soon.
     
  46. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    I will need to do some further testing but the best fix for the bug is simply removing the static constructor of
    ScriptableObjectInstantiator
    and / or remove the
    [InitializeOnLoad]
    Attribute from the class.

    This should be safe since the instances are created when accessed the first time automatically. The only downside is that the ResolutionMonitor would not be created after a fresh import (I will think about a smart solution here... I plan to make an installation wizard, but not sure if I find time for that in the near future).
     
  47. fkorsa

    fkorsa

    Joined:
    Dec 23, 2018
    Posts:
    9
    Actually I tried that, but then I had some error logs while building, because of recursive calls to EnsureInstance: the build calls OnValidate on some BetterUI components, which calls EnsureInstance, which calls Resources.Load, which again calls OnValidate on some other BetterUI components, which calls EnsureInstance again. I'm not sure those error logs actually do anything bad to the build, but I wouldn't dare messing up a production build.

    So for the time being, I am doing this:
    Code (CSharp):
    1. static ScriptableObjectInstantiator()
    2. {
    3.     EditorApplication.delayCall += Initialize;
    4. }
    Which actually doesn't work either in the specific case I mentioned - Initialize doesn't get called in that particular scenario. But in my CI script I invoke the delayCall event manually, which I think makes sense because that's for running something at editor start-up, after import. Anyway, I'm not sure there's a proper solution to that problem at all, sadly. But maybe you'll have more ideas than I had :)

    Thanks for investigating!

    It is only natural to contribute back, when you were generous enough to share the code with your customers.

    Cheers!
     
  48. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    I never noticed this problem. do you have the error log including a stack trace for me?
     
  49. fkorsa

    fkorsa

    Joined:
    Dec 23, 2018
    Posts:
    9
    Sure, here it is.
     

    Attached Files:

    • log.txt
      File size:
      65.7 KB
      Views:
      112
  50. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,050
    Thanks, but I couldn't find any error in the log...