Search Unity

Better UI

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

  1. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    BTW: Editing the better locator editor so that line 20 looks as follows at least fixes this problem.

    Code (CSharp):
    1.         bool autoPullFromTransform = false;
     
  2. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Hi @MaxGuernseyIII,
    Thank you for your bug report and also thanks for the suggested fix.
    To be honest, I never tested the Better Locator in nested prefabs. I add your Bug report to the backlog, so that it will be fixed in the next version.
     
  3. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Okay. 97% of my UI is in nested prefabs. So, for this one user, that fix is super important. A lot of the functionality that works in the scene editor does not work in the prefab editor.

    The line of code I posted was definitely not a fix. It was a workaround.

    I would love for this product to work as seamlessly in the prefab editor as it does in the scene editor and I will gladly provide whatever information you need toward that end.
     
    Hosnkobf likes this.
  4. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Also, as I'm going through your code, I'm noticing a lot of these:

    Code (CSharp):
    1. #if UNITY_EDITOR
    If memory serves, those don't play nice with Unity Cloud Build. I think you need to also declare that it is not unity cloud build, like this:

    Code (CSharp):
    1. #if UNITY_EDITOR && !UNITY_CLOUD_BUILD
    Although I see some lines like that in your code, too.
     
  5. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Okay. Here's an apparent fix:

    Code (CSharp):
    1. static IEnumerable<IResolutionDependency> AllResolutionDependencies()
    2. {
    3.   var allObjects = FindAllObjectsInScene(SceneManager.GetActiveScene());
    4.   if (PrefabStageUtility.GetCurrentPrefabStage() != null)
    5.   {
    6.     allObjects = allObjects.Union(FindAllObjectsInScene(PrefabStageUtility.GetCurrentPrefabStage().scene));
    7.   }
    ...and...

    Code (CSharp):
    1.  
    2.  
    3.         static IEnumerable<GameObject> FindAllObjectsInScene(Scene Scene)
    4.         {
    5.           foreach (var RootGameObject in Scene.GetRootGameObjects())
    6.           foreach (var Descendant in EntireLineage(RootGameObject))
    7.             yield return Descendant;
    8.  
    9.           IEnumerable<GameObject> EntireLineage(GameObject Ancestor)
    10.           {
    11.             yield return Ancestor;
    12.             foreach (Transform Transform in Ancestor.transform)
    13.             foreach (var Descendant in EntireLineage(Transform.gameObject))
    14.               yield return Descendant;
    15.           }
    16.         }
     
  6. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Also need to govern resolution dirtiness off of the current prefab stage like you do with other relevant properties.
     
  7. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Also, after making buttons and images better, they don't fire on click - at least not programmatically-attached click event handlers. I'm assuming this is a configuration issue. Maybe something to do with the raycast checkbox?
     
  8. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Nope. It wasn't the button. I was using the scroll view and fiddling around. Must've broken something accidentally and fixed it just as inadvertently.

    Also, the fixed I posted above doesn't work in unity cloud build because the experimental prefab stage isn't available, there. Since we don't need the prefab stage in production, we can just wrap the line that merges in the stage objects in a #ifdef.
     
  9. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Thanks for this suggestion, but actually the very most of these parts are for visual stuff or to get some information from certain editor windows which is both not available during cloud build. I successfully used Better UI in projects build with cloud build in the past. There shouldn't be any problem (if it doesn't work for you, please let me know and provide me error messages).

    Wow! This looks like a real fix. I will take your code as a reference for the fix in the next version. Thank you very much for your effort.

    So, the problem doesn't have to do with Better UI, right? Because assigning click events to a Better Button should work exactly like with a normal Button. You can even hold it as a Button (not Better Button) reference in your code and it should work.

    It is probably enough to put it in a
    #if UNITY_EDITOR
    section since it is something you only need during development and not during build time (like the other occurances I stated above).
     
  10. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    You can try that. As I said, earlier. #if UNITY_EDITOR doesn't work with unity cloud build because UCB (last time I checked) lies about whether or not you are in the editor. That's why you need both UNITY_EDITOR and NOT UNITY_CLOUD_BUILD - because we want to make sure the code doesn't run in production.

    In this case, as I said, the code I posted won't even compile on UCB, which makes it at least as critical that we filter the code out of UCB builds. ...and, as I said before, that cannot be done with just #if UNITY_EDITOR. At least, it couldn't last time I checked.
     
  11. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Yes, the other problem was a weird one but definitely not Better UI. Here's a Better UI issue I did notice. It has to do with the Make Better workflow and nested prefabs.

    When you use Make Better in a scene, it works exactly as you guess it should - everything just gets better. When you use Make Better inside a prefab, references to the component in the prefab seem to get broken.

    So, while you've made the prefab better, you did so at the price of having to find every place you use it and re-wiring the connections to it.

    I'm guessing this has to do with an auto-assigned ID and, if I'm right, I can't imagine any way around it other than forcing the new ID to be the same as the old one. The alternative would be to try to find every reference to the prefab in every asset - which sounds like a recipe for disaster. For people like me, who keep their .meta files as text, we can poke the right value into the file.
     
  12. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    One more thing. The anchor override thing works pretty well but there are a few peculiarities.

    One is that it appears there is an assumption that the source objects and the affected object share a parent. Maybe I'm wrong about that but setting the anchor source to a child of a sibling does not produce the results I expect.

    Another - and I haven't confirmed this but it seems to be the case - in complex situations, it works more reliably if the dependencies are earlier in the object list. If I'm right about that, it might be something to add to the troubleshooting section.
     
  13. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Ah, okay. That might be true. However, in the past I could do cloud builds with Better UI but it was with an older version. I have to double check if I broke something since then. Thanks for pointing out.

    For the same prefab it should work (since version 2.0). If the prefab is nested in other prefabs or it is instantiated in a scene (and you don't make the scene instance better), the references are not updated there, that is true. As you already pointed out, this is a very hard task to do. I will add it to my backlog anyways. Maybe I can find a way.

    No: The source object and the affected object can have different parents. Otherwise that anchor override component would be pretty useless.
    I never tried your use case (setting source object to child of a sibling) because I couldn't find a use case for such a setup. I don't see why this should not work, but I will try it myself.
    If you have an example scene for me where the anchor override doesn't work as expected, I would be happy to debug it for you :)
     
  14. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    For me, it was nested prefabs. I have a stylized button prefab that is nested all over the place.

    I have a feature request: Could you consider making a "better prefabs" thing? I'd like to be able to shelter certain changes from reverts, or prevent certain properties from being modified.
     
  15. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    I'll try to put something together. Even if it's just me using it wrong, you can probably find a note to add to the troubleshooting part of the documentation.
     
  16. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Yeah. I'm sure it builds - it just has some extra stuff. However, the code I posted uses the PrefabStageUtility class, which is experimental and not available via UCB (at least, not in an easy way).

    You are right. The problem I was experiencing is independent of parentage. The real cause of it appears to be the pivot of the parent (haven't checked whether it's the source or target parent).

    Try this:
    1. Set up a game object with three children (A, B, C, D).
    2. A is anchored at (0, 1)-(0, .8) with a Aspect Ratio Fitter setting width = height.
    3. B derives its Min X and Max X from A's Right using the Anchor Override component. Y anchors are 0.2 to 0.8.
    4. C is statically anchored at (.8, .2)-(.8, .8).
    5. D gets its Min X from B's Right and its max X from C's Left.
    All offsets are 0.

    If you play with the pivot for the parent, things go screwy really fast.

    I've solved this and some prefab-related problems by decoupling the object that does layout from the other UI concerns. For instance, the stylized buttons that are internally structured similarly to A, B, C, and D, above, are always anchored to (0, 0)-(1, 1) with a pivot of (.5, .5). The parent then can do whatever layout stuff it wants (like have a Better Locator) without affecting the internal structure of its child.

    This also allows me to reset the layout and the content independently.
     
  17. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    I don't really understand what you are looking for... Can you give me an example?

    Thanks. Please send it via Private Message or email.

    If it builds I don't see any need to change something. It doesn't matter if cloud build loads the editor-related code. The build will not contain it.

    Oh, thanks for pointing out. Seems like I have to extend my math to take pivots into account.


    PS: From tomorrow until January 7th I am in Christmas holidays. I might not look too often into the forums during that period.
     
  18. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Ditto.

    Not really. Not without attempting to dictate implementation. All I can state is the problem. The current prefab use experience gives you two options: revert everything for a prefab instance or revert one component at a time through a clunky navigation process.

    It would be nice to be able to set up logical groups of components within a prefab so you could revert one group and leave another alone.

    An example of that would be to have a Layout group and a Content group. The former could contain Rect Transforms, Layout Groups, and Better Locators. The latter could contain Better Text, Better Image, et cetera. Then, a nice UI that lets me set the layout for a prefab instance to match its origin layout without impacting any of the content.
     
  19. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    The editor hides the reliability of the Anchor Override behavior by only calling update once and often at the wrong time. What looks fine in play mode is hard to preview.

    This code overcomes that by making Edit mode act more like Play mode:

    Code (CSharp):
    1.  
    2.  
    3.         void OnDrawGizmos()
    4.         {
    5. #if UNITY_EDITOR
    6.           // Ensure continuous Update calls.
    7.           if (!Application.isPlaying)
    8.           {
    9.             UnityEditor.EditorApplication.QueuePlayerLoopUpdate();
    10.             UnityEditor.SceneView.RepaintAll();
    11.           }
    12. #endif
    13.     }
    The Anchor Override also has a legitimate (I think) bug - that or it's used in a surprising way. Changing the resolution - which happens whether the Anchor Override is enabled or not - triggers Update() and Update unconditionally rewires the anchors. This makes one of my use cases (where the overrides are usually disabled) very difficult and labor-intensive.

    Bailing out of Update for non-enabled behaviors solves the problem:

    Code (CSharp):
    1.     public void Update()
    2.     {
    3.       if (!enabled)
    4.         return;
    5.  
     
  20. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    The use case I was having trouble with, by the way, was this:
    • Keep separate graphs of game objects that specifically define the layout of the screen for one particular resolution.
    • Use anchor overrides to pull the anchors out of the layout objects.
    • Typically keep the anchor overrides disabled.
    • Occasionally enable them to pull updated layout data, then disable them and use your snap anchors feature to make an object's shape relative to the screen dimensions.
    Whenever I changed resolutions, my old save locator information were obliterated by the errant, indirect call to Update().
     
  21. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    I feel like the Anchor Override thing works really well but it would work better if it used the "driven properties" mechanism.
     
  22. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    I see that it can come handy for UI but as far as I understand this feature, it is related to prefabs in general, not especially to UI. Also, it sounds like a complex task to accomplish. So, this might be something for a different Asset on the store (maybe there already is one?).

    Thanks for pointing out. This and also the other update problem you mentioned is definitely not intended. I will change it in the next version. also thanks for suggestions for fixing this.

    Yes, that would make it easier to understand for the user. I added it to the backlog, but I consider it as "nice to have", since it doesn't add functionality.
     
  23. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Yeah. You're right that the effect is not UI specific. I bet the problem is approximately UI-correlated. Probably people who use prefabs for their intended purposes, rather than as a proxy for OOD in the editor, don't have the issue I'm having.

    There is an asset called "Nested Prefabs". I have a license but I gave up on it because it never worked well enough and then Unity made that a first-party feature. Maybe it's pivoting to add functionality like that. I'll check it out.

    No problem. Everything I've done is a hack and I'm looking forward to dumping it all in favor of the new version with proper fixes.

    I think it would also make things a lot easier for you. I suspect that Better UI and the event system will always be at odds in this area until the properties it drives are understood by Unity to be driven properties.
     
  24. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    I have it too and also had a lot of problems with it. I personally will not use it again and instead use the unity nested prefabs.
    Hmmm.... fair enough. So, let's make it a "should have" feature ;)
     
  25. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    I just checked and this appears to be the publisher's stance, as well. It is deprecated and renamed to have "LTS" added to its name. It resists being installed into a 2018.3+ project with things like a warning.
     
  26. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    I must admit, I'm having a bit of difficulty with the anchor override behavior. It seems like the offsets get changed to NaN a lot. I'm basically trying to jerry-rig a custom layout for my buttons with a border, an icon, and an area for text. I do this with sequences of anchor overrides and aspect-ratio fitters. Some set of (as yet) unidentified circumstances trigger the offsets to be changed from 0 to NaN.

    I'll keep hunting the problem and let you know if I find its source. Even if I'm doing something wrong, you can add it to the FAQ.

    Is this something you've seen, though? Do you have a hint where I should start looking?

    Also, I think a really cool and differentiating feature would be a rules engine that allows you to make an intelligent layout without creating a bunch of reference objects and defining anchor overrides.

    Attached is an example of the layout I set up using anchor overrides and aspect ratio fitters.
     

    Attached Files:

  27. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    I am sorry to hear you have such difficulties.
    I imported your prefab in a project with Unity 2019.2.3. I couldn't reproduce what you are saying.
    The "Icon and Text Layout" have two scripts attached I don't have, so I guess they are responsible for the problem.
    I guess they are changing the size or position of the margin and spacer objects. Otherwise you wouldn't need to use Anchor Overrides at all.

    Can you tell me which version of unity you are using and provide me the missing scripts?
     
  28. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    I'm using 2019.2. You're talking about "lock to parent", right? In the prefab I sent you, it's disabled. Here's the code, presented as is and without warranty (should anyone decide to copy it):

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. [DefaultExecutionOrder(5000)]
    5. [ExecuteInEditMode]
    6. public class LockToParent : MonoBehaviour
    7. {
    8.   public RectTransform[] ToLock;
    9.  
    10.   void Update()
    11.   {
    12.     if (ToLock == null)
    13.       return;
    14.  
    15.     foreach (var RectTransform in ToLock)
    16.     {
    17.       RectTransform.anchorMin = new Vector2(0, 0);
    18.       RectTransform.anchorMax = new Vector2(1, 1);
    19.       RectTransform.offsetMin = new Vector2(0, 0);
    20.       RectTransform.offsetMax = new Vector2(0, 0);
    21.     }
    22.   }
    23. }
    The fact that it's disabled notwithstanding, I can guarantee that's not the problem because I wrote it as an attempt to fix the problem. It doesn't happen every time. Only in certain circumstances. In fact, the asset I uploaded is used in the case where there is a problem but it's also used in a lot of places where there isn't a problem, too.

    Anyway, the asset I uploaded was an example of what I'm doing to simulate a custom layout. Not as a way of diagnosing the problem.

    No, they don't. The sizer/spacer objects are sensors They have aspect ratio fitters (which do change the size). Those are used to make sure that there is a margin that scales with the object but fixes together how the X and Y parts of the margin scale. Similarly, they are used to create space between the icon and text parts.

    I'm interested by the idea that I don't need anchor overrides to do this? How would you create a button layout that has a place for a square icon that fills the left part of the button except for a margin of uniform height and width that has a minimum size but scales with the size of the button and then has some padding to the right of the icon and fills the remaining non-margin space with an area for text?

    I'd love a simpler solution but this is the best I could find.
     
  29. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    I don't know. I just see two missing scripts at the top level object of your prefab.
    Would be nice if you could provide me some steps to reproduce.
    I know that there can be problems with rotated canvases or rotated UI-elements. The major problems I already fixed in the last two versions. But maybe there is something I am not aware of...

    Actually, I didn't understood your setup completely in the first place. what you are doing totally makes sense and the only alternative I can think of would be pixel-positions which makes problems with different resolutions (or an aspect ratio fitter for the top object). So, your solution is straight forward.
    The only thing you could change is getting rid of the guide parents. You could set the mode of the aspect ratio fitters to "Height Controls Width" then you can put them in the top level (or in one child of the top level to make the hierarchy less messy).
     
  30. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    They were both nothing.

    What I really wanted was a dynamic layout within my buttons but where some of the width parts are driven by the height part.

    I used this script, presented free to anyone who wants to take it with no restrictions on use and no warranty of any kind, to keep a layout element up to date and simulate having a working aspect ratio fitter within a layout:

    Code (CSharp):
    1. // Copyright © Hexagon Software LLC. All rights reserved.
    2.  
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. [ExecuteAlways]
    7. [RequireComponent(typeof(LayoutElement), typeof(RectTransform))]
    8. public class AspectRatioLayoutElement : MonoBehaviour
    9. {
    10.   public AspectRatioFitter.AspectMode Mode;
    11.   public float AspectRatio = 1f;
    12.  
    13.   RectTransform RectTransform;
    14.   LayoutElement LayoutElement;
    15.  
    16.   void Start()
    17.   {
    18.     RectTransform = GetComponent<RectTransform>();
    19.     LayoutElement = GetComponent<LayoutElement>();
    20.   }
    21.  
    22.   void Update()
    23.   {
    24.     if (Mode == AspectRatioFitter.AspectMode.HeightControlsWidth)
    25.       LayoutElement.minWidth = RectTransform.rect.height * AspectRatio;
    26.     else if (Mode == AspectRatioFitter.AspectMode.WidthControlsHeight)
    27.       LayoutElement.minHeight = RectTransform.rect.width / AspectRatio;
    28.   }
    29. }
    Once I had that, your better axis-aligned layout group solves the rest of the problems (like scaling margins and spacing).
     
  31. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    I'm having troubles implementing Better UI settings on background panel image that needs to have consistently thickness, as there's Avatar image that needs to be aligned to that curve and thickness.
    upload_2020-1-27_15-44-45.png

    In smaller resolutions, the border gets thicker and curvier, and higher resolutions the avatar floats of to the middle:
    upload_2020-1-27_15-50-10.png

    This game is portrait mode only,

    my background sprite is sliced and looks like this:



    upload_2020-1-27_15-49-25.png

    Is it possible to achieve CONSISTENT thickness and curvature of the border via better UI / image ?

    what would be the way to achieve this?
     
  32. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Hi @SlavomirDurej
    I think there are some problems to solve.
    The first is about your question. Because the character image has a rounded corner, the background image should have the same size of the corner. So the border should not resize or the character should do the same resizing.
    To not resize the border, you can either use simply an image (not a better image) or remove all size modifications. Then the border is resized based on the canvas scaler component in the main canvas.
    You would also need to adjust the anchors and / or pivot of the character image to keep it always at the right place.

    There is another solution which is a bit more flexible but requires some art changes:

    Art needed:
    - split the background into two parts: the inner part and the border (both should have the same size. The inner part has more transparency around and should overlap with the border a bit).
    - remove the rounded border part of the character image.

    UI Set up:
    - put the background image at the back and the border image at the front of the panel.
    - create a mask using the background image and make it as big as the panel (put it in between background and border)
    - make the character image a child of the mask, set the location, snap the anchors and move the pivot to the bottom.

    This way your character will always be at the right place and will have a rounded corner that perfectly fits in any situation. Because the border is a separate image on top, the hard cut out of the mask is hidden and it looks smooth and anti-aliased.


    Edit:
    Sorry, the mask approach is probably not so easy to achieve in your case because the character is bigger than the panel.
    If you cannot manage it yourself you can also send me the panel and I will take a look. I am not 100% sure how to solve your problem the best way without trying it out myself...
     
  33. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    yeah, the way the graphic is done none of the solutions works.. So we had to change the design at the end.
     
  34. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    @Hosnkobf is there a way to assign brightness to the BetterImage programmatically? Wanted to do a nice animated brightness "flash effect" on some UI elements, but couldn't find this option.

    Would be a real shame if this could only be applied in editor!
     
  35. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    @SlavomirDurej I guess you are talking about an Image with the "Hue Saturation Brightness" Material.
    Yes, you can change the parameters via code. It is probably not so obvious how, because the material properties are written into vertex parameters to allow the same material for multiple sprites with different parameters applied (resulting in a better performance when you have many sprites).

    You simply have to call
    SetMaterialProperty
    on your Image or RawImage.
    propertyIndex relates to the parameter in order they appear in the editor (zero based).

    here is an example:
    Code (CSharp):
    1. const int HUE = 0;
    2. const int SATURATION = 1;
    3. const int BRIGHTNESS = 2;
    4.  
    5. myImage.SetMaterialProperty(BRIGHTNESS, 2f);
     
    SlavomirDurej likes this.
  36. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    Ah , great, thank you! , (and yes it wasn't very obvious :) )
     
  37. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Better UI 2.2
    is released now!


    This release is mainly focusing on bugs which were introduced in Better UI 2.1 or occur in newer versions of Unity.

    Here is the change log:
    • Minor Changes
      • SerializedPropertyExtensions allowing also ScriptableObjects now instead of Components only, so they can be used by the end-user in more flexible ways now.
      • Anchor Override, Size Delta Sizer and Transform Scaler disable affected properties in RectTransform now.
      • Resolution Picker Editor-UI improvements
    • Bug Fixes
      • Resolution Picker can create resolutions of screen configurations now also in Unity 2017.3+.
      • Game Window doesn't recreate itself anymore.
      • Game Window is not focused after re-compile anymore if Resolution Picker is open.
      • Better Locator "Auto Pull" also work in Prefab Scene now.
      • Anchor Override also work correctly now if the pivot of the parent object is being changed.
      • Anchor Override updating logic fixed.
      • Anchor Override doesn't throw NullReferenceExceptions in certain situations anymore.

    Special thanks to @MaxGuernseyIII, @GiacomoGilli and Pascal Robert for their bug reports and ideas for solutions!

    I also looked into the reported problem that the references to nested prefab components get lost when they are converted to the better pendant. Unfortunately, this is a very tricky topic which I was not able to solve yet.
     
    nemeth-regime likes this.
  38. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    I have a problem setting material property programatically on BetterImage. It doesn't throw error but sprite is just black :(

    (Using the latest version from AssetStore)

    Here is a sample code:

    Code (CSharp):
    1.  
    2.  
    3.         [SerializeField] private Materials materials;
    4.    
    5. .....
    6.         currencyGo = new GameObject();
    7.         var tr = currencyGo.AddComponent<RectTransform>();
    8.         tr.SetParent(transform);
    9.         altCurrImg = currencyGo.gameObject.AddComponent<BetterImage>();
    10.         altCurrImg.sprite = altCurr_so.icon;
    11.         altCurrImg.material = materials.GetMaterial("Hue Saturation Brightness");
    12. ....
    13.  
    14.  
    materials is a Scriptable Object “Materials” from “Assets/TheraBytes/Resources” passed to this MonoBehaviour class.

    Then I am using my flash animator , to create a brightness flash on the BetterImage:

    Code (CSharp):
    1.  public class FlashAnimator
    2.     {
    3.         const int HUE = 0;
    4.         const int SATURATION = 1;
    5.         const int BRIGHTNESS = 2;
    6.  
    7.         private BetterImage img;
    8.         private Tween tween;
    9.  
    10.         public FlashAnimator(BetterImage img, float delay=0f, Action onComplete = null, float duration=.75f, float startValue = 6f)
    11.         {
    12.             this.img = img;
    13.  
    14.             tween = DOTween.To(FlashIn, startValue, 1, duration).SetDelay(delay).SetEase(Ease.OutQuad)
    15.                 .OnStart(() => AudioManager.Instance.playClick(AudioManager.CLICKS.FLASH_TINKLE))
    16.                 .OnComplete(() =>
    17.                 {
    18.                     onComplete?.Invoke();
    19.                     Destroy();
    20.                 });
    21.         }
    22.  
    23.  
    24.         private void FlashIn(float value)
    25.         {
    26.             if (img == null)
    27.             {
    28.                 Destroy();
    29.             }
    30.             else
    31.             {
    32.                 img.SetMaterialProperty(BRIGHTNESS, value);
    33.             }
    34.         }
    35.  
    36.         public void Destroy()
    37.         {
    38.             tween?.Kill();
    39.         }
    40.      
    41.     }
    none of this works when I do this via code, but it works when I set up BetterImage in prefab and manualy sellect the HueSaturationBrightness material in the Unity Editor.

    Maybe you can tell me what I'm doing wrong, or if this is even possible to do in code?

    Many thanks
     
  39. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    What type is
    altCurrImg
    ? The reason I ask is that I seem to recall some trouble accessing some Better UI objects via references to their base type. It could be another asset I use but, if I recall correctly, it's to do with some properties being redefined rather than overridden - maybe they weren't virtual in the base class or something.

    Again, I could be misremembering and I don't even know if that would apply to your situation... but it's probably worth a very quick check.
     
  40. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    field altCurrUmg is being created here:

    Code (CSharp):
    1. altCurrImg = currencyGo.gameObject.AddComponent<BetterImage>();
    the AddComponent method returns the component itself when being attached to the GameObject.
     
  41. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Hi @SlavomirDurej,
    I do not see, why the code would not work.
    However, there is a different way to do this.
    First, you do not need to reference Materials anywhere. It is a Singleton, so you can simply access it by
    Materials.Instance
    .

    But what you can try instead of doing all this yourself is letting Better UI handle the material assignment:
    Code (CSharp):
    1. //altCurrImg.material = materials.GetMaterial("Hue Saturation Brightness");
    2. altCurrImg.MaterialType = "Hue Saturation Brightness";
    Please also check in the inspector if the materials are assigned inside the Materials asset. if not, delete the asset and select
    Tools -> Better UI -> Settings -> Ensure Singleton Resources
    .

    Please let me know if that fixes your problem.
     
    SlavomirDurej likes this.
  42. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    This did the trick, thank you for your help.

    As a side note, some guidance in your help docs on how to use this via code (not just in Unity Editor) would be very helpful.
     
    Hosnkobf likes this.
  43. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    You are right. I added it to my backlog.
     
    SlavomirDurej likes this.
  44. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    Spoke too soon! Unfortunately, it doesn't work properly. While the images are no longer black, and the Hue Saturation Brightness material IS selected, there are no sliders for Hue Sat. Brightness, and even programmatically that flash animation doesn't work.
    upload_2020-7-6_15-10-32.png

    tried adding the material as well via GetMaterial, no difference, still no option to change HSB.
    Code (CSharp):
    1. private void addAltCurrency()
    2. {
    3.         currencyGo = new GameObject();
    4.         var tr = currencyGo.AddComponent<RectTransform>();
    5.         tr.SetParent(transform);
    6.         altCurrImg = currencyGo.gameObject.AddComponent<BetterImage>();
    7.         altCurrImg.sprite = altCurr_so.icon;
    8.         altCurrImg.material = Materials.Instance.GetMaterial("Hue Saturation Brightness");
    9.         altCurrImg.MaterialType = "Hue Saturation Brightness";
    10. }
     
    Last edited: Jul 6, 2020
  45. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Ok, I found the issue:

    Please open
    ImageAppearanceProviderHelper 
    and change
    SetMaterialType()
    so that the assignment of the value is before the
    UpdateMaterial()
    call.

    The resulting code is this:
    Code (CSharp):
    1.         public static void SetMaterialType(string value,
    2.             Graphic graphic, VertexMaterialData materialProperties, ref MaterialEffect effect, ref string materialType)
    3.         {
    4.             if (materialType == value && graphic.material != null)
    5.                 return;
    6.  
    7.             materialType = value;
    8.             UpdateMaterial(graphic, materialProperties, ref effect, ref materialType);
    9.         }
    the same bug is present in the method below
    SetMaterialEffect()
    .

    Please note that the image will turn black when you select it in Unity because the BetterImageEditor gets confused and overwrites the values with zeros.
     
    SlavomirDurej likes this.
  46. SlavomirDurej

    SlavomirDurej

    Joined:
    Oct 25, 2018
    Posts:
    32
    Yes, that has worked! thank you , really appreciate your help.
     
    Hosnkobf likes this.
  47. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    That is where you assigned the field. I was asking where the field was defined. Anyway, it sounds like you got it solved so it's all good.
     
  48. MotionBrain

    MotionBrain

    Joined:
    Dec 5, 2015
    Posts:
    36
    Hey,

    I'm getting somehow this error. I had this assets for a few days inside my project folder and didn't change a thing. I tried deleting your plugin and reimporting but nothing changes. Am I missing something?

    Assets\TheraBytes\BetterUI\Editor\Scripts\ResolutionSizer\SizeModifierDrawer\ScreenDependentSizeModifierDrawer.cs(29,13): error CS0103: The name 'WhowField' does not exist in the current context
    Assets\TheraBytes\BetterUI\Editor\Scripts\ResolutionSizer\SizeModifierDrawer\ScreenDependentSizeModifierDrawer.cs(85,17): error CS0103: The name 'WhowField' does not exist in the current context
    Assets\TheraBytes\BetterUI\Editor\Scripts\ResolutionSizer\SizeModifierDrawer\ScreenDependentSizeModifierDrawer.cs(86,17): error CS0103: The name 'WhowField' does not exist in the current context

    Regards
     
  49. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Hi @MotionBrain,
    looks like you accidentally renamed ShowField to WhowField somehow. Please double click on one of the error messages to open the script. make sure line 29 looks like this:
    ShowField(property, "OptimizedSize", "Optimized Size", ref sizer.OptimizedSize);

    line 85 like this:
    ShowField(property, "MinSize", "Min Size", ref sizer.MinSize);

    and line 86 like this:
    ShowField(property, "MaxSize", "Max Size", ref sizer.MaxSize);
     
    MotionBrain likes this.
  50. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Is there a way to use BetterUI for explicitly setting a layout, rather than inferring it from the screen resolution?

    Let me explain what I'm trying to so you can have a little context. I have a game it's kind of like a board game. All of the boards are pretty easy to see and understand on a normal device, but I'm adding a new one where you really want to have every square millimeter dedicated to the board.

    So I am adding a fullscreen mode, where all the extra stuff is hidden - stuff like the "return to main menu" button, the readout of in-game currency, et cetera. As a result, I really want two different layouts for my game and the ability to set which one is active in code.

    Ideally, this would be orthogonal to screen size. So I'd choose a layout group (fullscreen vs. all details) and within each of those groups, I could then have portrait, landscape, square, and super-tall.

    It seems like you have most of what is necessary to implement that - you've certainly solved a lot of the hardest problems in that space - but I don't know if it's a current feature.

    If it is, where do I look to find it?

    If it isn't, can I make a feature request to that effect?