Search Unity

[Source Code] DotsUI - open source UI framework for DOTS

Discussion in 'Data Oriented Technology Stack' started by supron, Jul 24, 2019.

  1. supron

    supron

    Joined:
    Aug 24, 2013
    Posts:
    48
    This is the first release of the DOTS UI system (https://forum.unity.com/threads/showcase-pure-dots-ui-system-detailed-description-feedback.688531). The source code is released under MIT license, so you can do anything you want with it. It's still very early development stage so don't be disappointed with lack of features and bugs. Remember, it started as a learning project and some parts of code are very ugly (strange class names, etc.).

    Link to the repository:
    https://github.com/supron54321/DotsUI

    I'd really like work full time on this project, but right now I can spend only 1-2 hours per day. That's why it took almost 2 months to publish this project, after my first post. I have rewritten the core from scratch a few times. Now I really like current design. It's fast, multithreaded and can be easily extended with new primitives and high-level controls.
    There is still A LOT of work to do before it will be production-ready. Check list of known issues and roadmap.

    Because of bugs in ConvertToEntity, the system is completely detached from this workflow and uses its own converters. In this version, the only "easy" way to work on UI is to convert Canvas hierarchy and prefabs through classes in DotsUI.Hybrid namespace. There is no high-level API for spawning pure UI Entities. I strongly recommend to convert unity prefabs to DotsUIPrefab and instantiate them form systems. Breaking changes in the core are pushed in almost every commit.

    Canvas render-mode must be set to "Screen-space camera". Conversion pipeline automatically adds a component to the camera (OnRenderImage hook).

    Design

    DotsUI is trying to convert UnityEngine.UI hierarchy to pure DOTS representation. Due to performance reasons, I removed rotation from RectTransform component. Scale will be implemented in future releases. The whole system is designed to achieve the best possible performance, but there is still room to make improvements (remove sync points, more jobs, and better data layout).

    Samples

    Documentation is not ready yet. You can check "PrefabExample" to learn how to create and instantiate DotsUI prefabs:
    https://github.com/supron54321/Dots...i.hybrid-samples/DotsUI.Samples/PrefabExample

    Contribution

    Right now I'm looking for the feedback. Share your thoughts about the idea of open source UI system. Once I finish the core, we can start with pull requests from the community.
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    431
    I think you should consider using the built-in conversion system. One thing I discovered relatively recently is that if Entities.ForEach doesn't let you do what you want to do, you can usually get around it by making an EntityQuery of the types you want and then getting the array of Entities from that. It's not as fast, but it might let you temporarily get around the RectTransform issue until the next Entities release.

    I do weekend game jams to build and battle-test my custom tech stack built on top of DOTS. If you can get this UI working with Unity's GameObject Conversion, I'd be more than happy to give you some battle-tested feedback!
     
  3. supron

    supron

    Joined:
    Aug 24, 2013
    Posts:
    48
    I will once issues with RectTransform are resolved. I implemented my own converters only because I needed anything to test UnityEngine.UI -> DOTS conversion.

    Still a lot of work to do, before its "battle-ready" :D
     
  4. mnarimani

    mnarimani

    Joined:
    Mar 27, 2017
    Posts:
    211
    I want to thank you for your awesome work. It's definitely something that I will be using in my future games.
     
  5. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    417
    Great job. Will have a look at it as soon as I'll be on a computer.
    I'm mostly looking for UI Text but by looking at the GitHub repo it doesn't seem to be available yet.

    Anyway thanks for this.
     
  6. supron

    supron

    Joined:
    Aug 24, 2013
    Posts:
    48
    Text is supported through text mesh pro component and fonts. Currently, "master" branch supports conversions from the following UI components:

    * Image
    * TextMeshProUGUI (SDF fonts, not all features are supported)
    * TMP_InputField (very simple implementation)
    * Selectable
    * Button
    * RectMask2D
    * CanvasScaler

    On develop branch I'm working on ScrollRect implementation.

    Unfortunately, ConvertToEntity is still not implemented. I encountered a critical bug in the conversion pipeline. I hope Unity devs can fix it soon. Right now the only way to convert Canvas hierarchy is to call RectTransformConversionUtils.ConvertCanvasHierarchy(Canvas, EntityManager).

    DotsUI works with unity 2019.3.0a8+. Hybrid UI renderer requires new Mesh API from 2019.3 (it's 2-3x faster).
     
    mnarimani and GilCat like this.
  7. mnarimani

    mnarimani

    Joined:
    Mar 27, 2017
    Posts:
    211
    @supron what kind of events does your UI support? (PointerDown, PointerUp, PointerClick, etc)
     
  8. supron

    supron

    Joined:
    Aug 24, 2013
    Posts:
    48
    • Down
    • Up
    • Click,
    • Enter
    • Exit
    • Selected
    • Deselected
    On develop branch I added support for:
    • BeginDrag
    • Drag
    • EndDrag
    • Drop
    I'll merge branches by the end of this week.

    Few words about low-level events (raw pointer and keyboard events). I considered different approaches for event handling. In early DotsUI development, I implemented events as components added to the target entity. That wasn't a bad idea, but it had few drawbacks. The first problem: it required entity data relocation and archetype change. Not bad if you have rare events like click or selection. Worse if you have a lot of frequently updated events (OnDrag, OnEnter+OnExit). The second problem: it required event queue cleanup at the end of the frame (another relocation). In the current DotsUI version, I implemented events as separated entities. Event entity archetype is very simple. It has PointerEvent component (with target entity) and PointerInputBuffer (dynamic buffer with eventID, eventType and eventData). This approach requires additional filtering job before per-target event handling, but it's very very fast (burst compiled) and avoids archetype changing. I even made a dedicated component system for auto target filtering.

    High-level events (ButtonClickedEvent, InputFieldReturnEvent, InputFieldEndEditEvent) are still components added to target entities. I'll probably leave it like this because high-level events must be easy to use and filter (simple entity query over typeof(MyButton), typeof(ButtonClickedEvent)). Overhead is minimal because these events are rare. Example usage: https://github.com/supron54321/Dots....Samples/PrefabExample/InstantiationSystem.cs
     
    GilCat likes this.
  9. supron

    supron

    Joined:
    Aug 24, 2013
    Posts:
    48
    New version merged on GitHub. Changelog:

    [0.2.0] - 2019-08-19

    Added

    * Added drag & drop support
    * Added ScrollRect

    Changes

    * Removed custom parent system. Now DotsUI uses Unity.Transforms
    * Updated entities packages
    * Updated obsolete API
    * Unit tests upgraded to latest changes in the core
    * Minor performance improvements
    * Updated roadmap
    * LegacyRenderSystem renamed to HybridRenderSystem
    * Improved idle performance of HybridRenderSystem (added RequireForUpdate EntityQuery)

    Fixes

    * Fixed issue with last few triangles not being rendered after InputField lost focus
    * Renamed folders in DotsUI.Hybrid
    * Removed unnecessary sync point in button system
    * Fixed exception in selectable system caused by NativeHashmap being overfilled
    * Fixed issue with canvas not being properly rebuilt after camera size changed
    * Canvas pixel size is now properly taken from camera size (instead of screen size)
    * Pointer events are now properly stopped from being propagated to parents


    ScrollRect doesn't support all of UnityEngine.UI features. It works only in one direction (Left->Right &? Bottom->Top), and it doesn't support scroll bar hiding. DotsUI doesn't support mouse scroll yet, so it's obvious it doesn't work in ScrollRect.


    [0.3.0] - 2019-09-08

    Added

    * Added support for ConvertToEntity
    * Added support for Screen Space - Overlay canvas rendering mode
     
    Last edited: Sep 8, 2019
    YurySedyakin, tanohmz, GilCat and 4 others like this.
  10. YurySedyakin

    YurySedyakin

    Joined:
    Jul 25, 2018
    Posts:
    7
    Hello,
    I've tried to convert a very simple scene from Unity UI to DotsUI. The setup is extremely simple - just a canvas with an image as a child object. The whole thing works when there is ConvertToEntity on Canvas game object. But I tried converting the Canvas into a subscene. At this point it broke. Not entirely, but it fails to convert the sprite asset. I've looked into the source a little bit, looks like you are adding sprites into destination entity manager using
    Code (CSharp):
    1. DstEntityManager.CreateEntity(typeof(SpriteAsset), typeof(SpriteVertexData));
    Instead, I believe you are supposed to use
    Code (CSharp):
    1. GameObjectConversionSystem.DeclareReferencedAsset(sprite);
    For this it looks like you need an additional system that updates in GameObjectDeclareReferencedObjectsGroup, and also you need to then convert declared sprite assets by their own conversion system. Anyway, I'm pretty new to this convertion workflow so I wasn't able to make it all work.

    Also it looks like DeclareReferencedAsset already adds a component object with the Sprite to the entity, so I guess you don't need SpriteAsset shared component at all.
     
    Last edited: Sep 17, 2019 at 4:33 PM
  11. YurySedyakin

    YurySedyakin

    Joined:
    Jul 25, 2018
    Posts:
    7
    Ok, I managed to fix Image conversion to work with subscenes. Added a system that declares referenced assets (Sprites) and another system that converts those declared sprite asset references by adding SpriteAsset shared component and also SpriteVertexData. For the whole thing to work I had to also create SpriteAssetProxy, make it [System.Serializable] and also make SpriteAsset [System.Serializable].
    Next: have to apply a similar fix to TextMeshPro font assets.
    And then: figure out if we can work without SpriteAsset shared component altogether, cause Sprite asset entity already has the Sprite component object. This isn't trivial because SpriteAssets being shared component gets addressed by shared component index later down the pipeline and my understanding is component objects are NOT shared components.

    Update: I managed to fix TextMeshProUGUI conversion to also work with subscenes, the whole thing works with subscenes now. I can provide the source code of the changes I made if needed.
     
    Last edited: Sep 18, 2019 at 4:54 PM
    supron and psuong like this.
  12. supron

    supron

    Joined:
    Aug 24, 2013
    Posts:
    48
    Good job! Can you create a pull request with your changes?

    SCDs are quite useful in optimization. I can use indices to batch similar materials in the job. Of course, it could be done without them.

    Btw. I have a little break from this project. I'll start commiting new features after the weekend.