Search Unity

[FREE, MIT] ⭕ Windinator - ⌨️ UI Framework - 〽️Procedural UI - ☄️ Flutter Inspired ⭕

Discussion in 'Assets and Asset Store' started by _BlenMiner_, Jul 21, 2022.

  1. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89

    Windinator allows to manage window flow and create UI directly through code or a hybrid between code and hand placed GameObjects. Includes Material design examples.

    Asset store is still updating the page, it will become free.
    Making this open source under MIT license:
    https://github.com/BlenMiner/Windinator

    What is Windinator?

    Windinator is a UI framework to help you create professional and personlized user interfaces for games or applications within Unity3D. It provides tools to manage window flow and navigation as well as tools to create user interfaces through code.

    Integrate in your Project

    Windinator works with the built-in Unity UI system, it was built to be compatible with existing workflows and other UI tools. You will need to have TextMeshPro imported inside your project since Windinator uses it for displaying text.

    Where to get it?

    https://assetstore.unity.com/packages/tools/gui/windinator-220506

    What are Windows?

    A window usually takes over the whole screen. When you create a window within Windinator, it will prepare a Prefab and a Script to go along side it. The prefab will contain a normal canvas that you can customize however you see fit. Once the window is created you can show it at runtime by simply pushing it to the stack:
    • Windinator.Push<Window_Type>();
    Later, if you want to close the window you can just pop it:
    • Windinator.Pop();

    What are Elements?

    Elements are optional, you can use your usual methods of creating your menus. But in case you need a more modular, code based approach to your designs then this is for you. Elements can be used to create smaller pieces of UI that you will manually integrate in your UI or use it inside other Elements, or fullscreen interfaces. They will also generate a prefab that will get updated automatically when the code updates.
    The syntax is very inspired by Flutter. There is no runtime overhead to this approach, all generation happens during editor time and gets saved to a prefab that you can use.



    Since elements are baked in the editor, there is no extra runtime performance penalty other than instantiating a simple prefab.

    Extras

    Windinator comes with some UI extensions. Namely a rectangle, polygon and line renderer.



    More Info

    WIP Documentation: https://gameobject.xyz/windinator/



    Core features/Overview:
    • Window Management/Flow with history
    • UI Generation through code (Flutter inspired)
    • Color palette system, highly customizable
    • Included Material UI design components and modules
    • UI Procedural Rectangle/Polygon/Line Renderer (Roundness/Shadows/Outline/Masks/Perfect AA)
     
    Last edited: Mar 3, 2023
    DragonCoder likes this.
  2. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Work in progress of a UI shape renderer and blender!
    The idea is to use this for organic and complex animations.

     
    RoyalCoder likes this.
  3. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Last edited: Sep 20, 2022
    MonkeyYao and RoyalCoder like this.
  4. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
  5. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
  6. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
  7. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
  8. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Working on a new update.
    It will have a new layer system for the dynamic renderer. It allows to draw on separate layers and then combine those layer! In this video example I'm drawing digits and blending between them:



    Live Demo: https://gameobject.xyz/demos/number-blending/

    Source Code:

    Code (CSharp):
    1. using Riten.Windinator.Shapes;
    2. using UnityEngine;
    3.  
    4. public class NumberBlending : CanvasDrawer
    5. {
    6.     [SerializeField] float m_thickness = 15f;
    7.  
    8.     [SerializeField] float m_animPower = 10f;
    9.  
    10.     [SerializeField] AnimationCurve m_animation = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
    11.  
    12.     Vector2[][] numbers = new Vector2[][]
    13.     {
    14.         // 0
    15.         new Vector2[] {
    16.             new Vector2(0f, 0f),
    17.             new Vector2(0f, 1f),
    18.             new Vector2(1f, 1f),
    19.             new Vector2(1f, 0f),
    20.             new Vector2(0f, 0f),
    21.         },
    22.         // 1
    23.         new Vector2[] {
    24.             new Vector2(1f, 1f),
    25.             new Vector2(1f, 0f),
    26.         },
    27.         // 2
    28.         new Vector2[] {
    29.             new Vector2(0f, 1f),
    30.             new Vector2(1f, 1f),
    31.             new Vector2(1f, 0.5f),
    32.             new Vector2(0f, 0.5f),
    33.             new Vector2(0f, 0f),
    34.             new Vector2(1f, 0f),
    35.         },
    36.         // 3
    37.         new Vector2[] {
    38.             new Vector2(0f, 1f),
    39.             new Vector2(1f, 1f),
    40.             new Vector2(1f, 0.5f),
    41.             new Vector2(0f, 0.5f),
    42.             new Vector2(1f, 0.5f),
    43.             new Vector2(1f, 0f),
    44.             new Vector2(0f, 0f),
    45.         },
    46.         // 4
    47.         new Vector2[] {
    48.             new Vector2(0f, 1f),
    49.             new Vector2(0f, 0.5f),
    50.             new Vector2(1f, 0.5f),
    51.             new Vector2(1f, 1f),
    52.             new Vector2(1f, 0f),
    53.         },
    54.         // 5
    55.         new Vector2[] {
    56.             new Vector2(1f, 1f),
    57.             new Vector2(0f, 1f),
    58.             new Vector2(0f, 0.5f),
    59.             new Vector2(1f, 0.5f),
    60.             new Vector2(1f, 0f),
    61.             new Vector2(0f, 0f),
    62.         },
    63.         // 6
    64.         new Vector2[] {
    65.             new Vector2(0f, 1f),
    66.             new Vector2(0f, 0f),
    67.             new Vector2(1f, 0f),
    68.             new Vector2(1f, 0.5f),
    69.             new Vector2(0f, 0.5f),
    70.         },
    71.         // 7
    72.         new Vector2[] {
    73.             new Vector2(0f, 1f),
    74.             new Vector2(1f, 1f),
    75.             new Vector2(0.5f, 0f),
    76.         },
    77.         // 8
    78.         new Vector2[] {
    79.             new Vector2(0f, 0f),
    80.             new Vector2(0f, 1f),
    81.             new Vector2(1f, 1f),
    82.             new Vector2(1f, 0.5f),
    83.             new Vector2(0f, 0.5f),
    84.             new Vector2(1f, 0.5f),
    85.             new Vector2(1f, 0f),
    86.             new Vector2(0f, 0f),
    87.         },
    88.         // 9
    89.         new Vector2[] {
    90.             new Vector2(1f, 0.5f),
    91.             new Vector2(1f, 1f),
    92.             new Vector2(0f, 1f),
    93.             new Vector2(0f, 0.5f),
    94.             new Vector2(1f, 0.5f),
    95.             new Vector2(1f, 0f),
    96.             new Vector2(0.5f, 0f),
    97.         },
    98.     };
    99.  
    100.     void DrawNumer(CanvasGraphic canvas, Vector2 size, LayerGraphic layer, int number)
    101.     {
    102.         var nb = numbers[number];
    103.         var hs = size / 2f;
    104.  
    105.         for (int i = 0; i < nb.Length - 1; ++i)
    106.         {
    107.             canvas.LineBrush.AddBatch(nb[i] * size - hs, nb[i + 1] * size - hs);
    108.         }
    109.  
    110.         canvas.LineBrush.DrawBatch(m_thickness, layer: layer);
    111.     }
    112.  
    113.     protected override void Draw(CanvasGraphic canvas, Vector2 size)
    114.     {
    115.         int time = Mathf.FloorToInt(Time.time) % 10;
    116.         float lerp = Time.time % 1f;
    117.  
    118.         var numberA = canvas.GetNewLayer();
    119.         var numberB = canvas.GetNewLayer();
    120.         var result = canvas.GetNewLayer();
    121.  
    122.         DrawNumer(canvas, size, numberA, time);
    123.         DrawNumer(canvas, size, numberB, (time + 1) % 10);
    124.  
    125.         canvas.Blend(numberA, numberB, Mathf.Pow(m_animation.Evaluate(lerp), m_animPower), result);
    126.         canvas.Copy(result, canvas.MainLayer);
    127.  
    128.         result.Dispose();
    129.         numberA.Dispose();
    130.         numberB.Dispose();
    131.     }
    132. }
    133.  
     
  9. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Quick update, the package is now compatible with older android versions. Any device should be able to run it.
    Performance is still a work in progress. I'm trying to optimize the layout system since it seems to be the core issue right now.
     
  10. ledshok

    ledshok

    Joined:
    Oct 28, 2012
    Posts:
    28
    Looks really interesting!

    Suggest you link to this thread from the asset page itself (I only found it by googling).
     
    _BlenMiner_ likes this.
  11. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    1,701
    If you ask me, you should publish the SDF system as a separate asset that's just included with this UI system.
    It seems like it could be used for quite some things or even the main feature in a casual game.
     
    _BlenMiner_ likes this.
  12. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    I agree that this package is made up of essentially sub-packages. The SDF system, the window managing and the ability to create UI only through code. My main reason was that unity kept taking my package down for "being too simple". I will give it some thought.

    I have been planning on lowering the price of the asset, do you think that would help your point or separating it is best?

    By the way, the new update brings the performance to a new level too.
     
  13. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Just for fun I tried to make a procedural sticky panel using the SDF system!

     
  14. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Introduced a new polygon brush that allows for some cool effects!
    This expands the existing rectangle, circle and line drawing by giving you the ability to draw any filled shape!

     
  15. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Update is now live!
     
  16. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    Juicy!
    Are there replacement to the default button hover? It's such a pain to have to set an animation for buttons.
     
  17. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Well if you use any one of the procedural shapes for the graphic of the button there is a script that comes with the extra Material stuff that does that material circle expanding effect, it can be added along side the default Button script.


    I'm still expanding on all the features and the Material extras are still a WIP at this point so any feedback is welcome.
     
    Last edited: Sep 27, 2022
    laurentlavigne likes this.
  18. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    Windinator is so bloody good that I have to hold back making UI.

    It's got rough edges though so. I was chatting with _Typhoon about them but Reddit chat ain't the best so here it is:
    1. undo doesn't work - at all most of the time and to some other value in some cases.
    2. using log4net
      found its way in one of the script, I don't know how that made it passed the AS team but deleting that line fixed it.
    3. when I dropped CanvasGraphic's quality below 1 for the Rectangle object in the Wobble Example/ComplexShapes scene, the bar disappeared and when I brought quality back up to 1 it stayed gone. I couldn't recover and had to reload the scene, I later discovered that I could press play, also in play mode these things break.
    4. circle pos Y value keeps changing, is that the internal dynamic thingy that makes it wobble?
    5. In the sticky panel example when moving the leftmost panel to the right there is a piece of clipped panel that appears to the right of the middle panel (sticky panel is so awesome, and the code so clean that I'll be able to customize it)
    6. when canvas is set to World or Camera mode, Windinator component switches it to overlay, I tried debugging that for an hour when I saw this pearl:
      upload_2022-9-26_17-10-28.png
    Now onto the suggestions:
    1. add an ID# to sticky panels so that we can have layers of stickiness overlapping without interacting. I think it's 5 lines of code, and thinking about it, people will put the wrong ID and then blame it on the asset so I wouldn't bother.
    2. no script contains the name Windinator so it's a bit hard to add components since no keyword can be typed that auto-populates the list. Mudbun in contrasts has Mud* as prefix so it's super easy to compose shape, even if I don't read the manual (*whistle*). If that's not possible because of legacy user base, then a toolbar would be nice. My personal preference goes towards using Unity's interfaces because it's very good at that. So if the user base is small, I say refactor the Monos, I don't think classes have a [FormerlyKnownAs("Prince")] so instead you can keep them as empty shell and do
      class OldCrustyClass : WindiAwesomeNewClass
      .
    3. add a few tooltips for the weird stuff
     
    Last edited: Sep 27, 2022
    _BlenMiner_ likes this.
  19. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    Is one of them a procedural shape? upload_2022-9-26_11-29-32.png
    I just discovered that MaterialIcon is a unicode component! That's very cool.
    I like discovering good surprises but I still think it should be called something more obvious like Windi_UnicodeIcon

    Here is what I've seen in other assets. It's a nice way to explain stuff and include a tuto at the same time.
    upload_2022-9-26_11-38-19.png
     
    _BlenMiner_ likes this.
  20. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    A few other questions coming your way, as I've been ignoring all gameplay code, having way too much fun making UI, instead:
    • How would I set the color of the small circle so that, as it detaches from the large circle its color peels off too?
      upload_2022-9-26_14-42-47.png
    • ̶I̶ ̶u̶s̶e̶ ̶l̶a̶r̶g̶e̶ ̶s̶h̶a̶d̶o̶w̶s̶ ̶w̶h̶i̶c̶h̶ ̶c̶l̶i̶p̶s̶ ̶s̶o̶ ̶I̶ ̶e̶x̶p̶a̶n̶d̶ ̶t̶h̶e̶ ̶D̶y̶n̶a̶m̶i̶c̶B̶a̶r̶ ̶r̶e̶c̶t̶ ̶s̶i̶z̶e̶,̶ ̶b̶u̶t̶ ̶i̶t̶'̶s̶ ̶u̶s̶i̶n̶g̶ ̶O̶n̶P̶o̶i̶n̶t̶e̶r̶ ̶w̶h̶i̶c̶h̶ ̶u̶s̶e̶s̶ ̶t̶h̶e̶ ̶r̶e̶c̶t̶a̶n̶g̶u̶l̶a̶r̶ ̶a̶r̶e̶a̶ ̶t̶o̶ ̶d̶e̶t̶e̶c̶t̶,̶ ̶s̶o̶ ̶t̶h̶e̶ ̶m̶o̶u̶s̶e̶ ̶g̶e̶t̶s̶ ̶d̶e̶t̶e̶c̶t̶e̶d̶ ̶w̶a̶y̶ ̶t̶o̶o̶ ̶e̶a̶r̶l̶y̶.̶ ̶I̶s̶ ̶t̶h̶e̶r̶e̶ ̶a̶ ̶w̶a̶y̶ ̶t̶o̶ ̶s̶o̶l̶v̶e̶ ̶t̶h̶a̶t̶?̶ EDIT: increase expandBorders
    • I changed the way that rectangle's circular indentation behaves and named it... ready?.... RectangleWithCircularIndentations, I know, it's a mouthfull. It's now got a RectTransform array, and loops through the circle centers to add CircleBrush draw commands (are all the draw commands batched?) Problem is the effect is offset
      upload_2022-9-26_14-36-9.png
      that's happening with this code that seems correct, can you help?
      Code (CSharp):
      1. [ExecuteAlways]
      2. public class RectangleWithCircularIndentations : CanvasDrawer
      3. {
      4.     public RectTransform[] circleCenters;
      5.     public float circleRadiusMultiplier = 70f;
      6.     public float blend = 80f;
      7.  
      8.     protected override void Draw(CanvasGraphic canvas, Vector2 size)
      9.     {
      10.         var expand = 200f;
      11.         canvas.RectBrush.Draw(new Vector2(0, -expand - size.y * 0.5f), new Vector2(size.x, size.y + expand));
      12.         foreach (var circle in circleCenters) canvas.CircleBrush.Draw(circle.anchoredPosition, circle.transform.localScale.x * circleRadiusMultiplier, blend, DrawOperation.Substract);
      13.     }
      14. }
    • I added button component to the Icon objects but they don't react or fire up the OnClick event . What's the right way to do this?
     
    Last edited: Sep 26, 2022
  21. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    1) I'm waiting for an update to be validated which improves undo/redo.

    2) Also fixed with the new update

    3) So, the reason it gave some issue with that example in specific is because it was using "Dirty Mode" drawing, which just means it was optimized to only update the texture when necessary. Since the slider clears the texture and nothing draws to it, it just stays empty. This is fixed too with the new update.

    4) Not 100% what you mean but the way I made that circle wobble was by having 3 other circles inside it with dynamic blending. So by making them get closer to the surface it expands it. I didn't have the polygon brush then so it can also be made with the polygon brush which might make more sense.

    5) Yeah this example has some issues when multiple panels get close, I never got to fixing it as I didn't give it too much priority and it was just a concept idea I was playing with. I might eventually get back on that and improve the system.

    6) This is also fixed with the new update. It also works better when in world mode.

    Thanks for the suggestions I will surely consider them for the next updates.

    The procedural shapes can be found under this menu: https://gameobject.xyz/windinator/images/DynamicUI/AddCanvas.png
    Yeah, the icons are rendered with TextMeshPro!
     
  22. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    So Color blending is on my TODO list but it's not yet possible. Each shape can have a color or a gradient. I plan on adding Textures support and colors in the future but not yet.

    So usually if you want to position drawings based on other rects you can use "Canvas.GetRect" or even "Canvas.SetRect".

    And to answer your questions about batching, to batch you need to call "AddBatch" and finally "DrawBatches".
    When using the "Draw" function you are creating a batch for every call.

    "I added button component to the Icon objects but they don't react or fire up the OnClick event . What's the right way to do this?", make sure the textmeshpro text has raycastable toggles on.
     
  23. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    That was it, thanks.
    O the possibilities, new types of UI.

    Is there currently a way to add a embossing effect? Spherization effect with a highlight like in Mudbun?
     
  24. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Can you show me what you want to achieve?

    But as of right now you probably can't achieve this. I'm assuming if its just around the shapes it can be procedurally calculated in the shader using the SDF data. And it might be a fun thing to have. Although I am sort of running out of space to send extra data to the shader without sacrificing batching. I already compress a lot of the data to fit everything in there.
     
  25. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    something like that upload_2022-9-27_13-24-37.png

    and spherize would be an extension of that with inner shadows and the ability to push the highlight further away from borders:
    upload_2022-9-27_13-26-54.png
     
  26. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    My humble opinion is that this looks like something that I'd find fun to try, but is a bit too niche at the current price with only a couple reviews. Maybe try putting it on sale or gifting it out to generate more reviews?
     
    Last edited: Sep 28, 2022
    laurentlavigne likes this.
  27. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Well it allows better UI management in general, the SDF stuff is just to enhance your UI creation and is only part of what the package has to offer. But I can understand why it might not be very clear. I can't control when sales happen unfortunately and I have been gifting it out once in a while with my reddit posts and even here on the forums sometimes.

    ps: I plan on doing an overview video to help introduce the asset better.
     
    Last edited: Sep 28, 2022
    laurentlavigne likes this.
  28. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    An overview video would be good, as currently you don't have any videos showing "this ui is made from code". People like me only watch the videos, so they miss out on what the "element" system is. A video that showing that part would help rubes like me understand.

    Lame that people didn't leave a review after taking a key. I have some time this weekend - if you toss me one I'll test it out and leave a review.
     
    Last edited: Sep 28, 2022
    laurentlavigne likes this.
  29. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Well I can't seem to start a conversation with you to send it.
    ps: the voucher that is.
     
    Last edited: Sep 28, 2022
  30. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    I don't think that's the problem here, people have left reviews so there might be a minimum cap before reviews are published. @_BlenMiner_ I think you get a AS rep you can speak to and see what's up.
     
  31. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    Perhaps there's a moderation queue or something for the reviews. Your review was just published within the last day, do you remember when you wrote it?
     
  32. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    Weird, I think the one I created went through.
    edit: Got it, weird it only worked one way.
     
    Last edited: Sep 28, 2022
  33. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    I see it now. It only took hours so it's not the moderation queue backlogged, it's really the score threshold that's not met yet. So you were right, not enough people who were gifted the plugin leave reviews, that and I'm sure that voucher assets get weighted down.
     
    Last edited: Sep 28, 2022
  34. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    To be faire, most of the vouchers I gave away were just sort of there. I didn't ask people for reviews in exchange, I just left a key and who got it .. got it. So I assume that most people that got it through a voucher might not even have downloaded it, they just redeemed it because a free asset is always welcome. Which, there is nothing wrong with that and I sort of expected it.
     
  35. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Here is my first round of tests, is this what you were looking for?

     
    laurentlavigne likes this.
  36. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    Exactly!

    Regarding Windinator-SDF, artists prefer components over codes. We (i'm both but always prefer doing visual things with visual tools) want to add an SDF to a gameobjects (where it acts like a rect shape) or a shurikens (where it becomes a per particle SDF thingy).
    Say I want to carve a wobbly square hole in a UI? I add the square shape and set its operator to substract then add the wobble component and it'll wobble the shapes segments for me when there is movement in the gameobject.
     
  37. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    I understand that, but I think I will stick with code forward approach as the whole package is code oriented. Adding a system that uses gameobjects and components to render stuff should be possible with the existing stuff anyway, most of the work would be to generalize everything and include batching in a smart way. I would like to add it at some point, just not now.
     
    Last edited: Sep 30, 2022
  38. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    Hey guys, hoping you can help me spot the bug. I'm trying to modify the number blend example to work as a countdown timer instead, but I think I messed up the blending somehow? DrawNumber() now draws 2 digit numbers and my Draw() function in my project looks like this:

    Code (CSharp):
    1.  
    2.     protected override void Draw(CanvasGraphic canvas, Vector2 size)
    3.     {
    4.         float lerp = Time.time % 1f;
    5.  
    6.         canvas.Clear(m_numberA);
    7.         canvas.Clear(m_numberB);
    8.    
    9.         DrawNumer(canvas, size, m_numberA, counter);
    10.         DrawNumer(canvas, size, m_numberB, counter-1);
    11.  
    12.         canvas.Blend(m_numberA, m_numberB, Mathf.Pow(m_animation.Evaluate(lerp), m_animPower), canvas.MainLayer);
    13.     }
    14.  
    I'm updating the values by calling the following function every second with a decremented number:

    Code (CSharp):
    1.     public void DisplayNumber(int number)
    2.     {
    3.         print("changing to " + number);
    4.         counter = number;
    5.         if (counter < 0)
    6.             counter = 0;        
    7.     }
    I can see in the console logs that it's being called once per second.


    I see a timer correctly animating its countdown from 20 correctly in the example scene with:
    Code (CSharp):
    1.  
    2.     protected override void Draw(CanvasGraphic canvas, Vector2 size)
    3.     {
    4.         int time = 20 - Mathf.FloorToInt(Time.time);
    5.  
    6.         canvas.Clear(m_numberA);
    7.         canvas.Clear(m_numberB);
    8.  
    9.         DrawNumer(canvas, size, m_numberA, time);
    10.         DrawNumer(canvas, size, m_numberB, (time - 1));
    11.  
    12.         float lerp = Time.time % 1f;
    13.         canvas.Blend(m_numberA, m_numberB, Mathf.Pow(m_animation.Evaluate(lerp), m_animPower), canvas.MainLayer);
    14.     }
    So I'm not sure why it looks so janky in my project's actual scene.
     

    Attached Files:

    Last edited: Oct 2, 2022
  39. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    I feel like the numbers are blending backwards maybe? Try inverting the lerp value by doing (1 - lerp) at some point or on the blend function.

    Or keep track of the time in a float instead of using Time.time and use that instead. By decreasing it you should get proper blending automatically. Be ware of negative time numbers, the modulos can return interesting things.

    ps: another simple solution could be swapping the layers when blending
    canvas.Blend(m_numberA, m_numberB
    would become
    canvas.Blend(m_numberB, m_numberA
    . This is because your "newest" value is your lowest value now, the opposite of before.
     
    Last edited: Oct 2, 2022
  40. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    Made a comparison as simple as possible between using a Time.time which blends correctly, and using a different integer:

    Shared code swapping out lines 6 and 7:
    Code (CSharp):
    1. protected override void Draw(CanvasGraphic canvas, Vector2 size)
    2. {
    3.     canvas.Clear(m_numberA);
    4.     canvas.Clear(m_numberB);
    5.  
    6.     //int newInt = 30 - Mathf.FloorToInt(Time.time);
    7.     int newInt = battleManager.localTurnTimer;
    8.     if (counter != newInt)
    9.     {
    10.         print(newInt);
    11.     }
    12.     counter = newInt;
    13.  
    14.     DrawNumer(canvas, size, m_numberA, counter);
    15.     DrawNumer(canvas, size, m_numberB, (counter - 1) > 0 ? (counter - 1) : 0);
    16.  
    17.     float lerp = Time.time % 1f;
    18.     canvas.Blend(m_numberA, m_numberB, Mathf.Pow(m_animation.Evaluate(lerp), m_animPower), canvas.MainLayer);
    19. }
    Console output with newInt set from battleManager - Janky number blending:
    upload_2022-10-2_15-37-54.png

    Console output with newInt set from Time.time - smooth number blending:
    upload_2022-10-2_15-41-5.png

    I have no idea how this could be producing different results. Both decrement the same variable exactly one time per second.
     
  41. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Did you try the suggestion I gave you above?
    Also if battleManager.localTurnTimer is a float, you can just do:
    float lerp = battleManager.localTurnTimer % 1f;
     
  42. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    I did try those suggestions yeah, still the same behavior.

    If I take the working line 6 and change it to
    int newInt = 30 - Mathf.FloorToInt(Time.time  + 0.33f);
    I see the same kind of jank. I'm guessing it's because the lerp float timing no longer lines up with the int value changing.

    localTurnTimer is just an int, not a float. At least I have an idea of what's incorrect now.
     
  43. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    Finally think I have it resolved with:


    Code (CSharp):
    1.     protected override void Draw(CanvasGraphic canvas, Vector2 size)
    2.     {
    3.         canvas.Clear(m_numberA);
    4.         canvas.Clear(m_numberB);
    5.  
    6.         if (counter != battleManager.localTurnTimer)
    7.         {
    8.             timeChangeAt = Time.time;
    9.             counter = battleManager.localTurnTimer;
    10.         }
    11.  
    12.  
    13.         DrawNumer(canvas, size, m_numberA, counter);
    14.         DrawNumer(canvas, size, m_numberB, (counter - 1) > 0 ? (counter - 1) : 0);
    15.  
    16.         float lerp = Time.time - timeChangeAt;
    17.         canvas.Blend(m_numberA, m_numberB, Mathf.Pow(m_animation.Evaluate(lerp), m_animPower), canvas.MainLayer);
    18.     }
    Let's not talk about how long that took to figure out :)
     
    Last edited: Oct 2, 2022
    laurentlavigne and _BlenMiner_ like this.
  44. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    How do you think this is feasable?
     
  45. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    Yeah, not sure, still debating how I can approach texturing in an easy powerful way.
     
  46. Crzed

    Crzed

    Joined:
    Oct 19, 2013
    Posts:
    27
    One thing I wanted to point out - I normally show/hide various UI windows by disabling the canvas component (I imagine others do as well). Child objects with Windinator's Draw() methods still run invisibly when the Canvas is disabled though. Would be nice if I didn't need to do an extra step to disable that too.
     
    _BlenMiner_ likes this.
  47. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    ^ that
     
    _BlenMiner_ likes this.
  48. _BlenMiner_

    _BlenMiner_

    Joined:
    Jun 10, 2015
    Posts:
    89
    I have recently started work on the texturing system.
    Very early but here are some also early results:

    (The rectangle & triangle are just embossing, its already on the latest update)

    Here is 3 textures being blended into one another:
     
    Crzed likes this.
  49. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    nice start. emboss will help sell it. also since you use SDF you probably can warp the texture at the edges to fake thickness.
     
  50. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,365
    I think you'll need a thickness for the emboss: one panel with a small thickness fusing with one panel with high thickness will create a highlight between them, as if doing this SDF operation on real 3D object
    to get this:
    upload_2022-10-9_12-9-9.png