Search Unity

Building Material Design UI

Discussion in 'Works In Progress - Archive' started by bac9-flcl, Oct 14, 2014.

  1. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829


    Images aren't very interesting, though - have a video instead:

    Long story short, I got a bit tired of implementing controls from scratch in every project and overall from using unstructured UI workflows. Seriously, why am I still using awkward window managers that are created anew every time, why do I have to deal with setting up tweens and sprite references when adding a spinner and why do I need custom switches, buttons and show-hide sequences every time? I shouldn't be doing that.

    So I started working on a coherent MVC based foundation (using NGUI) that will allow me to create interfaces that are quick to set up, easy to maintain and easy to expand.

    While at it, I thought to myself - wouldn't it be wonderful if I had not just nice code providing reusable elements, but also those beautifully implemented controls from Material Design by Google that native Android developers enjoy? Wouldn't it be nice to have Unity applications that can fool a user into believing they are native? Anyway, how hard would implementing controls from Material Design guidelines would be?

    ________________

    Turns out they are quite a bit complex, but every single one of them can be implemented without atrocious hacks or performance-hungry workarounds like frame-based animations. For example, those switches are just three overlayed sprites that require no custom masking - just proper order of color and scale tweens.



    The most complex things here are touch effects and shadows. Those were a complete mystery to me - for all I knew, Google implemented them with magic. Check these animations:


    Only idea I had at first was using NGUI panel clipping in every element, but that was unacceptable from performance standpoint and would have cluttered the hierarchy - and that would only allow those radial ripples, without addressing even more mysterious second part of the animation - inverse erasing of the expanding ripple sprite, which can't be achieved through traditional rect-based clipping at all. But as it turns out, it can be implemented, at almost no performance cost, and with that double clipping from within.

    You set up a separate UIPanel set to hard edge clipping, with a component that can set it's dimensions and position, with a singleton to access it, and a child ripple sprite that can tween through the touch animation. Any touchable widget can call the singleton and invoke a method (using itself as an argument) on touch, which will reposition the UIPanel clip area to dimensions of a widget arriving in the argument and start the ripple animation in the clicked point of the screen.



    Now only thing that is left is the second clipping - erasing the ripple sprite from within. That one is achieved by creating clipping-compatible depth cutout shader (no need to modify the example, just give NGUI a properly named duplicate) and applying it to a UITexture with the circle texture, then moving the object with it outside of the UI plane to allow depth testing to kill pixels within the panel. All you need to do when that is set up is to tween the ripple sprite first and the eraser sprite second, and you get yourself that nice, impossible ring that is required for every clickable element in Material Design.



    ________________

    Another area where Material Design presents a huge challenge is dynamic shadows. They are not in any way similar to the standard static drop shadows that people bake into sprites.



    They are dynamic, with every rectangular element capable of lifting back and forth through multiple depth levels, casting very smooth shadow of variable feathering radius. That's extremely problematic. But as it turns out, it can be implemented too, with some clever trickery. Take a look:

    To do this, I prepare a sliced sprite with rectangular shadow and assign it to the sprite anchored without any offsets to my card. There is no need to do it manually - I just add a "sprite shadow" component to a UISprite object and everything is set up automatically (and cleaned up when that component is removed).

    The desired look, with variable feathering radius, is impossible to achieve with standard sliced sprite behaviour and anchoring in NGUI. Using that custom component, I subscribe to the fill event of the sliced shadow and directly modify the positions of 36 vertices, pushing the central quad instead of all quads to be controlled by the sprite dimensions and anchoring, and pushing the other quads outward depending on offset calculated from the depth, then finally sampling a certain curve to get proper shadow intensity. Ah, and the sprite is offset downward a bit, depending on the depth.

    ________________

    Not sure if that webm hosting has limits on the traffic (sites accepting 15s+ files are hard to come by), so just in case, here is a mirror (379kb):


    ________________

    P.S.: To inevitable question of "why not uGUI", well, I really prefer NGUI for a number of reasons.

    • First, uGUI is unlikely to get the sort of personal tech support that NGUI had for years. Unity forums and issue tracker are nice and dandy, but not really comparable to the developer himself answering every single question.
    • Second, I prefer depth based draw order to hierarchy based draw order and dislike uGUI dependency on the hierarchy sorting
    • And third, simply by virtue of existing for a very, very long time, NGUI has thousands of threads, posts, docs, tutorials and other things that allow you to learn faster, and allow you successfully find on the net solutions to most of the problems you might encounter. uGUI will solve that over time, but has not accumulated that amount of material around itself yet.
     
    John3D, Jaex and Kirbyrawr like this.
  2. misterPantoni

    misterPantoni

    Joined:
    Feb 7, 2013
    Posts:
    44
    This looks really well done - i really like the way you created those button touch-circles. I definately would buy this in the Asset store...
     
  3. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Input fields in two varieties (yet to make a multiline one):



    Works with any content text size, automatically adapts the control widget size to make guidelines-compliant spacing easy, can work on any background.
     
  4. LazyPoet91

    LazyPoet91

    Joined:
    May 20, 2014
    Posts:
    35
    I really like the idea. would be awesome to play games with the feeling that they are native apps of the system. I am no dev but I read all your explanations with much interest (didn't understand all, but hm :D)
    Good luck with this :) Material Design is awesome and should be everywhere.
     
  5. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Spinner: controlled through a method with 0-1 float as an argument, value that can be fed with the progress on some operation or alternatively just produced from delta time in update. The method constructs the color by sliding through HSB, while rotation and fill completion are evaluated from two relatively simple custom AnimationCurves that intersect to provide the catch-up impression.



    Multiline input:



    Thanks! I agree, the whole style is awesome and incredibly versatile, not to mention how guidelines themselves are example of absolutely perfect design documentation that are both very informative and in-depth while being easy to follow and educational.
     
    Last edited: Oct 17, 2014
  6. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Did some work on screen control.



    At the moment it works like this:

    • UI is split into overlays and screens, each controlled by their managers
    • Overlays include touch ripple panel, focus ripple panel, and stuff like full-screen fills that appear behind on sidebar/dialog opening. Overlays are not concerned with each other and their manager is only exposing methods allowing to call them in isolation: for example, to create a ripple somewhere, or block the screen for something. Overlays don't care if they are opened or otherwise used simultaneously, they fulfill different roles each. That whole part is created automatically.
    • Screens are containers that define what the user is seeing when interacting with a certain distinct area of an application. In various situations they can be called tabs or windows, but those words just describe the look. Screens themselves have bare minimum of functionality: their manager keeps track of them all and provides exposed methods to show a certain window, either by direct reference or by ID number. Manager takes care of closing previously opened windows and other mundane stuff like that.
    • Screens are parents to areas: every screen can have one or multiple areas. Easy way to think about them is to think of them as paper sheets from Google guidelines - you drop them onto the canvas to create layouts, you use them to house your content, you slide them in and out of the screen. Areas implement show/hide functionality called by their parent screen (optionally exposing slide out direction and distance to allow you to create complex transitions Google heavily employs) and are the first entities to actually create anything visual: areas optionally control the creation of the "paper" sprites along with their perceived depth (through the shadow effect described above). Each area is housing a UIPanel, so that's also the first and last entity allowing you to control relative depth between parts of UI layout.
    • After that, you can do whatever you want in the bounds of an area. You can of course jump directly into adding labels, buttons and sprites, but there are few abstracted entities to make common use cases easy: for example, Content entity that creates a widget and sets up few most common content types anchored to it within (for example, text with a header and proper margins, or a dialog layout). Another example is ScrollView entity that sets up a panel, scroll view, table, scroll bar and some other stuff for you, allowing control with a simple parent widget.
    So, the most simple UI design goes like this:

    • Create screen manager object
    • Create a screen underneath it
    • Create an area in that screen
    • Create a content entity in that area, set to one of predefined types
    • Interact with the content entity (view presenter) from your controller

    Of course, no one is stopping you from setting up whatever internal layout you want in every area by using labels, buttons, switches and separators (all of those are parent entities wrapping and constructing certain NGUI design, of course - you don't have to deal with setting up tweens in a switch animation or shadows in a button).

    Creating any entity type is a matter of adding a component to an empty GameObject. The component checks what objects are required for it, and if they are not present, creates them following in-built presets (for a flat rectangular button that would be creating one sprite, one label, a control widget and a collider for it). Presets can be very varied and can be switched on the fly - a switch can transform itself into radio, checkbox or a toggle slider with just one enum selection in it's inspector. The component also provides a method (and a context menu option) to destroy it along with all connected objects and components, which is handy when you don't want to clean up that stuff yourself.
     
    John3D and LazyPoet91 like this.
  7. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Had some progress. I'm navigating with a mouse in the following gifs, but GifCam is not capturing the pointer for some reason.



    This time, I tried to create a simple note-keeping application with few options (list, editor, tagging, removal, etc.). Can easily be expanded into a quest log or, say, Mass Effect style codex.

    The results are pretty neat. My process is pretty simple - I'm trying not to develop stuff on the basis of "oh, that might be useful" - instead, I choose a project, work on it, and observe what I dislike and miss in the process. When something is a problem, I fix that.



    The scene hierarchy goes like this:

    Code (csharp):
    1.  
    2. VPScreenManager
    3. └   VPScreen
    4.     └   VPArea
    5.         └   Various content
    6.  
    There are following basic entities:
    • Screen manager: Keeps track of all screens and provides methods to open/close/toggle them if you have screen ID or screen object reference. Those methods request appropriate action from screens themselves, nothing complex happens in the manager.
    • Screen: Holds part of UI you want to show or hide from the user in it's entirety. Header bar, sidebar, window, photo gallery, contact window, browser tab, - all of those and many more are screens. Screens are split into two distinct types: isolated and unified. There can only be one unified screen visible at a time: like a browser tab or an app section like settings, for example, belong to that type. Screen manager ensures that whenever a unified screen showing is requested from anywhere, every other unified screen should stay hidden. Isolated screens, on the other hand, have no connection to anything else: things like sidebars and pop-up overlays belong to that type. They do not care what else is open at the time and screen manager makes no attempt to hide other screens when an isolated one is called. Screens also expose event delegate lists onEntry and onExit, allowing very easy control over presentation: for example, a sidebar screen can call overlay manager on entry and exit to get the dark overlay obscuring screens below, like you see on the gifs. Another example is a page with a list of notes that can request a refresh of the list from a controller before it is presented - you, again, see this in a gif above. Both isolation toggle and delegate lists remove any need to maintain inconvenient piles of event delegates on entities like screen switch buttons - you no longer need to explicitly set up what should be shown, hidden, and called from every single navigation button.
    • Area: Foundation of a screen, every one of them contains at least one area. Area view presenter wraps NGUI UIPanel and performs actual alpha/position changes should show/hide/toggle be requested from it's parent screen. You can customize the entry direction and position shift. For example, the sidebar in the gif above is a screen with one area, Left entry direction and position shift value equal to it's width. A screen can contain multiple areas to allow complex depth setups or complex entry animations - like a mosaic that flies into the screen at different speeds and from different directions. Aside from panel control and entry/exit animation, area does little, and it's usually not accessed directly from any entity but it's parent screen.
    None of those three create anything visual. They do not control a single sprite. Now though, after those are set up, under any area, you can drop a wide variety of view presenters, including your own, to actually create a visible layout and allow interaction. Few examples:
    • Sheet: Creates a simple shadow casting paper sheet and provides some exposed properties like types from guidelines (card vs tile) or shadow depth. Can be used for initial layout setup.
    • Separator: Creates a separator line across the selected widget in a selected direction with optional margins - useful when your layout consists of multiple docked paper sheets that never travel independently - you can then just draw one area and split it with lightweight separators.
    • Button: Well, creates a button. Very rich element - it allows you to select one of the five button types from Google guidelines (flat rectangular, raised rectangular, icon-supported flat rectangular, round floating action and flat icon buttons), provides all imaginable properties depending on the type (icon reference, colors, text, and so on) and provides an event delegate list for subscription. Optionally, it can also pass bool, int, float, string or object arguments on click, which NGUI button can't do. That's how the auto-generated buttons in the note list depicted in the gif above work - they have no custom components on top of them, they simply send an int with a document ID to allow the controller to open a right one. Again, that allows less clutter and less time spent doing manual setup.
    • Switch: Similar to button, but provides one of the three switch types from Google guidelines (toggle, radio or checkbox). Keeps track of required objects, provides event delegate list, and so on.
    • Content template: Simple entity that creates on the few very widespread content types in the bounds of a widget (uniform text, titled text, dialog, etc.). Keeps track of proper per-type anchoring, clamps widget size to prohibit inappropriate rescaling and so on. Useful when you need to whip up a layout filled with simple text quickly: just create a paper sheet and anchor a content template to it.
    • Input field: Creates an input field with all the fancy line control, hint handling and other niceties dictated by Google guidelines. You can see it both in the gifs above and in the previous post.
    It's also extremely easy to create your own view presenter entities if your application has some unusual elements not covered by existing types. I added two for that particular example:
    • Screen announcer: Subscribes to screen manager and feeds the name of the currently active screen to a label, with a fancy animation. You can see it in the upper left corner in the gifs above
    • Scroll list card: A simple entity that mostly exploits existing types, wrapping them. Creates a paper sheet, covers it with a flat rectangular icon button, adds scroll view drag component, text preview label and some other minor things. Allows the sample controller from the gifs above to set up that scrollable document list easier.
    The whole application depicted on the gifs takes few hours to set up at most: the controller and model are pretty short and UI work is mostly dragging ready-made entities in the scene view. It's not a static demo, it's data-driven UI that loads documents from files and saves them back. Pretty neat.

    Next time I'll try something more complex, maybe an inventory with tabs, dropdowns and previews.
     
    Last edited: Oct 25, 2014
  8. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,123
    Excellent work can't wait to see this mature. Will you be seeking this as an asset or releasing it as opensource?
     
  9. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    No fancy gifs this time, but nevertheless, nice progress. The one thing I was extremely worried about is screen density handling.

    Usually, you think about your UI design in pixels. That button is 48 pixels tall, that anchor offsets a widget by 16 pixels, and so on. That's a great way of doing it on traditional desktop games where resolutions and screen densities are pretty predictable and no one bats an eye about size of the elements unless they get a small 4K screen. Mobile platforms, on the other hand...

    You usually want your buttons, or text fields, or other stuff to be around 0.7-1cm high for good balance between usability and amount of content on the mobile screen. Tiny problem is, there are smartphones with 480px 4' screens, and there are smartphones with 2160px 5' screens, and there are tablets, and there is insane wealth of other size+density combinations. So using pixel-driven control size, you will easily get this:



    Ugh. What are your existing options?

    • Use Constrained UIRoot: Nice, but you say goodbye to pixel perfect elements. Do you really want to have your UI scaled to x2.1723454 on some device? Not really, you'd probably prefer it to be x2.
    • Use Adjust by DPI on Flexible UIRoot: Very nice option, retains pixel perfect UI on 96dpi screens and fools UIRoot into thinking it has a different resolution on a different DPI, allowing you, for example, to use absolutely identical values for non-Retina and Retina iPads while getting pixel perfect UI on both. Except many devices do not properly report their DPI so you'll be stuck with one size fits all platform-dependent assumption like 160dpi. Except most devices do not have the DPI multiple of 96, so say goodbye to nice proportional scaling. Except some devices combine relatively high DPI with relatively low resolution so you might want to use a lower DPI layout there instead of unbiased scaling to allow your layout to fit at all.

    Okay, that's not a very attractive situation. You want this on every single device, no matter how nice it's resolution is and how weird it's screen size is:



    Well, that problem is already solved in native UIs. Android has a very nice approach to solving that very issue:
    https://developer.android.com/guide/practices/screens_support.html

    There are few important ideas:
    • Do not use pixels, set up everything using virtual units (Android calls them DP, density independent pixels)
    • Translate virtual units into physical pixels depending on the DPI of the screen
    • Do not actually use true DPI of the device, because calculated scaling multiplier will most likely be absolutely awful - instead, sort all devices into broad groups by their DPI and force those groups to use unified, preferably integer scaling multipliers like 3x
    Nice, but how can we do that in NGUI? Turns out it's pretty simple. We have mentioned the experimental Adjust by DPI mode above, and it actually does a very similar thing, except it's reliant on true DPI and real multipliers. So, I just replaced NGUIMath.AdjustByDPI call in UIRoot with my own and created this simple component:



    Replacing atlases aside, it does this:
    • You can assign screen density bucket (like HDPI) in the editor to directly preview how your UI will look on a device belonging to that density
    • When you change that option, the component checks the screen resolution and, if necessary, drops the DPI bucket selection down until it fits the guidelines: it's important to remember that, for example, even if a device belongs to XXHDPI (480DPI) density, unless it has a screen bigger than 960 pixels, it absolutely can not fit enough content on the screen and should be forced to use a lower bucket
    • After the check is passed, the component updates the multiplier (1x for MDPI, 3x for XXHDPI, 2x for XHDPI and so on) in the static class that returns adjusted height for UIRoot
    With this slight change, Adjust by DPI UIRoot mode is perfectly usable! Well, ahem, for Editor work, that is. I still need to ensure that builds will automatically force a proper density depending on device. NGUIMath.AdjustByDPI fetches the DPI, but I wonder if any improvements are possible there - for example, maybe it's possible to ask an Android device it's real density bucket directly, in a way native apps do that.

    Depends on the interest - I started it as a personal project for my own convenience. Do you think it has potential as an Asset Store product?
     
  10. TheValar

    TheValar

    Joined:
    Nov 12, 2012
    Posts:
    760
    I think it probably has some potential as an asset store product. For me personally the fact that it's built on NGUI would be a deal breaker but a lot of people out there DO use NGUI.

    Anyway this is very awesome!
     
  11. pluhn

    pluhn

    Joined:
    Jul 27, 2010
    Posts:
    42
    I'd pay for something like this for sure. NGUI is great, but I spend so much time creating and tweaking my own UI components that I wish there were premade components I could just drop in and be done. The fact that you're implementing Google's extremely impressive Material Design makes it all the more appealing.
     
  12. ThinEze

    ThinEze

    Joined:
    Aug 25, 2014
    Posts:
    1
    Can't wait to see this on Asset Store.
     
  13. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Great news, full support for screen density buckets and in-editor density previews is working:



    You can now work with any screen density right in the editor, which is especially nice when you have properly prepared all atlases (for 160dpi, 240dpi, 320dpi, 480dpi and 640dpi). I did prepare them, of course - all five atlases, 440 core images each, with proper slicing, resolution, color, atlas scaling, etc. Murdered whole day converting and preparing them from SVG sources by Google. Will probably bundle those resources with the release if it's not prohibited by the license. They are suprisingly lightweight, never topping 1024x1024 atlas size even with insane 640dpi resolution very few devices on the market have.

    Only thing that I'm yet to add and would like to have is in-editor support for shrunk high-density previews. It's mostly relevant for people with small screens who want to preview ultra-high density layouts that can't fit into Unity window at true scale. Right now, like on deployment to devices, density bucket is dropped until you reach minimum allowed screen resolution for a given bucket. Can't stretch your viewport past 960px? You can't display 480DPI (XXHDPI) layout in it. So I would like to add an option to allow you to sacrifice 1:1 pixel perfect view in favor of scaled one.

    _______________________________________

    In other news, had a look at shadows again. I was never fully satisfied with how my dynamic shadows only shifted outward from the widgets and had quite a boring linear gradient, giving them impression of a cheap photoshop effect.



    For all the nice look, they weren't really similar to the shadows detailed in guidelines:



    So I charted those values into curves, fixed some obviously erroneous values from above that broke those curves, and had a go at rewriting the shadow implementation. Some would say it does not matter, some would say shadows looked alright as they were - sure, maybe. I might leave the old and simple implementation as a low-quality optional mode. But I'm adding a new one, and doubt anyone will want to go back. For a minor performance cost, you get this beauty that completely replicates offline quality you get from layered Photoshop/Illustrator effects. In realtime:



    It's driven by three curves (blur, offset, alpha) referenced from the guidelines, and is using an altered post fill method that takes a lot of stuff into account (visibility of the shadow at low radius, separate inward/outward offsets, etc.) and damn it's satisfying to see it work. As always, it's completely automatic: you just add a component to a sliced sprite object and get a slider driving the shadow, and when you remove that component, child sprite it was employing is cleaned up.
     
  14. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Worked on some refactoring today, so not much to show. But I added one new fancy visual tool: .aco importer! Those files are Photoshop format containing color palettes (swatches) and are widely used to distribute palettes accompanying various design documents. You can download one here, for example: http://www.google.com/design/spec/resources/color-palettes.html

    Now you can load one straight into Unity:



    You can use it with the standard screen-space color picker from Unity to color your NGUI widgets in a consistent manner. You can also assign those colors to screens, allowing entities controlled by them to automatically use consistent coloration. Pretty neat time saver.

     
  15. omarzonex

    omarzonex

    Joined:
    Jan 16, 2012
    Posts:
    158
    wow

    yeah Menu Automatic

    very cool
     
  16. PuneetK

    PuneetK

    Joined:
    Sep 2, 2013
    Posts:
    75
    Hey man, this is seriously amazing and something I was looking for.

    I was wondering if you've got the code available somewhere so we can use this in it's current state? Couldn't see a link in the post anywhere
     
  17. Allen0012

    Allen0012

    Joined:
    Sep 5, 2009
    Posts:
    93
    Wow this is very interesting. Great job!

    I'm definitely interested in buying git access to your WIP repository and start using it. :)
     
  18. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    After wrestling it for few days, finally got it working. Fancy clipped screen transitions straight out of apps like Google Inbox!



    NGUI has support for clipping panels with textures, but you can not clip nested panels and can not use simple scaling to tween the field as it will wreck underlying reparented layouts. Add to that some trigonometry (I really should have paid attention to that at school) to calculate the appropriate final radius for the furthest screen corner and the need to make this work with previously implemented sliding transitions, and I had a lot on my plate. Thank goodness it ended up working without the need to resort to cheap trickery like full screen opaque fills with fadeouts.

    _______________________________

    As about early access, I'm very flattered by the interest, but I think it would be a supremely bad idea at the current point in development. Do you really want to start using a system at a point in it's development where classes appear and disappear every day, properties change constantly, scenes get wrecked by changing requirements to UI hierarchy, and all manner of other icky stuff is going on?
     
    Last edited: Nov 4, 2014
    jbw and BrunoMikoski like this.
  19. BrunoMikoski

    BrunoMikoski

    Joined:
    Feb 25, 2014
    Posts:
    5
    What tween solution you are using? Please tell me you're not using the NGUI one.

    Another thing, use ScreenToGif for the gif capture, is way better than GifCam!
     
  20. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Haha, no way, it's not very convenient. I'm using LeanTween, mostly LeanTween.value with custom evaluation methods.
     
  21. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    One particularly inconvenient issue with designing UIs for multiple screen resolutions and densities is how you need radically different proportions and layouts to cover all cases nicely. You don't want lines to span a 4k display horizontally and you don't want your sidebar to eat precious horizontal space on a narrow smartphone screen. So you need to make design responsive.

    Uh, well, I solved that, more or less.



    I thought about the issue a bit and found a somewhat elegant solution.

    1. First, to avoid absolutely horrifying math involved in managing non-overlapping interval lists, I implemented screen resolution intervals through making simple int lists where you define not intervals, but midpoints between them. You can define any amount of midpoints you want - for example, 320px, 480px, 720px, 960px and 1280px in the case of that gif.

    2. After that, you can manage a list of layout groups, which contain a GameObject list and two integer sliders allowing you to select the resolution bracket from points you have entered before. Then simple validation logic hides and shows stuff as necessary.
    Current implementation looks like this in inspector:



    A bit ominous (I can probably get neat color coded interval visualization going for every group), but very easy to use.
     
    Last edited: Nov 5, 2014
  22. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Great news everyone! Responsive layout system progressed very nicely and is pretty different now from object-based draft I showcased above. First, to remind you what responsive layouts are, simple illustration:



    There were two biggest issues with the previous implementation:
    • You had to set up the objects in one centralized and unintuitive custom inspector that was disconnected from real UI hierarchy, which is far cry from intuitive and fast anchoring editor every NGUI widget offers you on selection of particular widget within the hierarchy.
    • The implementation used simple enabling/disabling of GameObjects, and you really don't want to deal with that most of the time: imagine having half a dozen of functionally identical data-driven scroll lists instead of one, it's awful.
    Both of those issues are out and workflow is much more straightforward now.
    • First, you set up desired resolution brackets. For example, maybe you want to have one layout for screens of below 480dp width, another layout for screens between 480dp and 640dp width, and another layout for screens wider than 640dp. Easy! Just set up your intervals with this neat array in the screen manager (featuring auto-configured clamping to nearest neighbors with fancy sliders and warnings):
    • Second, add a new component to any UI widget you want to be density dependent. Depending on amount of resolution intervals set up in your screen manager, that component will store appropriate amount of anchoring configurations. The component is not attempting to replace the perfect anchoring editor from NGUI - you still use the familiar controls, except you can save your configuration to one of the resolution brackets. Set up your anchoring for a narrow screen, click the copy button on narrow configuration, set up your anchoring for a wide screen, click the copy button on widescreen configuration. Done.

    The screen manager maintains a list of resolution-based anchor components and swaps anchoring configuration to appropriate one depending on detected resolution, giving you results like this while keeping your data-driven UI free from pesky duplicates or other inconveniences. There is no need to set up dozens of resolution-based anchoring configurations either - in some applications, the whole design can be hierarchically anchored to just one widget, necessitating just one collection of configurations on that topmost widget.

    Aside from this goodness, I worked on some other stuff like refactoring and new view presenters. One of the new object types is the dropdown menu. While still work in progress, it's already looking quite good:



    • It's using just one label for all the options: no separate labels/colliders/delegates, which conveniently prevents hierarchy clutter and instantiation costs on option list length changes. I get the selection from local touch position.
    • As usual, everything is animated through a simple evaluation: one tweening method with 0-1 float argument does all the magic with sliding offsets, sheets, shadows, spacing, colors, etc. No dozens of tweener instances, no Unity animations, clean and fast.
    • It expands from the list position of a selected value, just like guidelines dictate. Tricky to combine with this animation, but as you can see, it works.
     
    Last edited: Dec 10, 2014
  23. kintz_09

    kintz_09

    Joined:
    Apr 9, 2014
    Posts:
    3
    This is amazing! I really want to redevelop our product UI using Material Design but I didn't think that would happen because we are using NGUI. We use NGUI because our software runs in stereoscopic 3D and NGUI is best in that. Since this is based in NGUI, would you expect it to function in a 3D and stereoscopic 3D environement?
     
    Last edited: Dec 10, 2014
  24. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Well, NGUI camera can render to texture (like cameras working with other UI solutions can, actually), so I don't see any issue blocking NGUI UI use in 3D. Just assign a material with produced render texture to a 3D object like a curved plane. Detecting input might require some work if you want that UI plane in a 3D scene to be interactive, but otherwise it should be okay.

    I used NGUI on a 3d plane in a simple Oculus Rift based game without any issues.
     
  25. pluhn

    pluhn

    Joined:
    Jul 27, 2010
    Posts:
    42
    This continues to look amazing. Are you planning for an eventual Asset Store release?
     
  26. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Absolutely, once it's reasonably stable. I'm skeptical about releasing in early alpha stages - it's not a shader set or something similarly simple in terms of upgrade path, and at the current stage I can't guarantee that ongoing updates won't wreck your projects on a daily basis. Too much stuff is not set in stone yet and might be changed, breaking compatibility with existing scenes.
     
    FrojoS likes this.
  27. Allen0012

    Allen0012

    Joined:
    Sep 5, 2009
    Posts:
    93
    It would be great if you could give me any sort of timeline of when you think it'd be in release stage. Anything like in next month to next 6 months and next year would be great info.
     
    FrojoS likes this.
  28. ibps13

    ibps13

    Joined:
    Oct 6, 2012
    Posts:
    113
    Hi bac9-flcl,

    I'm NGUI long time user, very interesting project, any news to make this to assetstore product ?

    thanks,
     
  29. Christian-Tucker

    Christian-Tucker

    Joined:
    Aug 18, 2013
    Posts:
    376
    Who gave you permission to implement bootstrap with Unity? Joking, Joking.

    But very nice work.
     
  30. RIw

    RIw

    Joined:
    Jan 2, 2015
    Posts:
    90
    How can I make so beautiful designed UI (step by step) ?? :O
    I must know!
     
  31. sonicviz

    sonicviz

    Joined:
    May 19, 2009
    Posts:
    1,051
    +10 on status update!

    Doing a redesign of my UI atm (NGUI 2.7 + NDATA) and conflicted between new uGUI or NGUI 3.

    Any update?

    I'd really like to implement a scrolling table for settings, with each cell containing unique setting or control.
    Also conflicted over hamburger/side menu vs tab menu for design.
    Side menu's seem to be getting a bad rap nowdays.
     
  32. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    The development is on hold right now - my thesis takes more of my free time than I have expected so I'm unable to do much work on this asset and my other personal projects. No promises, but I hope to continue development around April once that timesink is out of the way. :)

    Google developed incredibly well-presented and detailed guidelines on the subject, available here: http://www.google.com/design/spec/material-design/introduction.html

    That's pretty trivial even with the current unfinished state of the system (sans some not yet implemented control types like sliders if some settings require those).

    I'll have to disagree, there is nothing fundamentally wrong with either. They are separate elements used in very different cases, though, so choosing between them is not really a thing. Tabs and side nav have distinct use cases:

    http://www.google.com/design/spec/layout/structure.html#structure-ui-regions-guidance
    http://www.google.com/design/spec/layout/structure.html#structure-side-nav
    http://www.google.com/design/spec/components/tabs.html#tabs-usage

    Both (and many more nav/menu types from the guidelines) should be supported by this asset. Side nav already works (it's pretty simple in structure) and tabs are technically possible too (they are just a special case of buttons, what's lacking is a wrapper to group them under dimensions of one UIWidget and implementation of some distinct visual effects from the guidelines).
     
  33. Play_Edu

    Play_Edu

    Joined:
    Jun 10, 2012
    Posts:
    722
    Hi_Awesome Stuff man. can this Work with NGUI or Not?
     
  34. Domino-Studios

    Domino-Studios

    Joined:
    Oct 26, 2012
    Posts:
    31
    Hello,

    did you plan a github for collaboration purpose ?
    I am at a state of my project which I will rely to material design. I work in a MVC pattern with the StrangeIOC framework (a must have) to handle the data and I will be happy to help.
     
  35. fac

    fac

    Joined:
    Sep 20, 2013
    Posts:
    1
    Hi, I'm looking to get Material Design on UNity, your demos look very good, I've just found this project: https://github.com/InvexGames/MaterialUI

    Can you tell me how does it compares to your code?

    If your project is still alive how much will it cost and have you an ETA?

    Thanks in advance
     
  36. LinusOhman

    LinusOhman

    Joined:
    Nov 13, 2013
    Posts:
    1
    Been lurking this thread for awhile, any news or updates?
     
  37. nahoy

    nahoy

    Joined:
    Dec 10, 2012
    Posts:
    21
  38. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    @nahoy

    Hey! Are you u/Saxy_Man from r/unity3d who was posting images of uGUI based Material Design system? Great to see that your work has evolved so much!

    I'll send you a PM with my contact info.
     
  39. nahoy

    nahoy

    Joined:
    Dec 10, 2012
    Posts:
    21
    Hey!

    No, I'm not Declan, but the French guy who work with him for the past months to bring MaterialUI to the Asset Store ;)
    You can send us an email at contact@materialunity.com if you want.
     
  40. Akif-Ali-Khan

    Akif-Ali-Khan

    Joined:
    Sep 18, 2013
    Posts:
    1
    @bac9-flcl

    Hey! Is this plugin available to asset store?
     
  41. unity_iVc2RJJJOSRdeg

    unity_iVc2RJJJOSRdeg

    Joined:
    Nov 19, 2018
    Posts:
    4
    This is awesome. Is this plugin still available?