Search Unity

Other [0.9.4] Latios Framework for ECS megathread

Discussion in 'Entity Component System' started by DreamingImLatios, Dec 21, 2019.

  1. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    A quick feedback: fatal error related to Myri 0.4.3
    upload_2022-3-26_16-39-18.png

    Happens when adding dozens of prefabs that attached with audio source authoring component and entering play mode and crash, reduce prefabs of those then OK, prefabs with NONE audio source authoring component result OK too.

    The `DeclareReferencedPrefabs` and `Convert` of audio prefabs funcs are completed.

    I'll check 0.4.4 later~
     
    DreamingImLatios likes this.
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Oomph. This one is brutal, and unfortunately one I am going to have difficulty reproducing since it is likely computer-specific. It is one of two issues, and I'm going to need your help determining which it is.

    You will need to embed the package (have the package inside the Packages folder, which you can do by cutting and pasting from the Library/PackageCache) and then navigate to Myri/Authoring/ClipsAndListenersConversionsystem.cs.

    In 0.4.3 through 0.4.5, the line of concern is 95. Change the Allocator from TempJob to Persistent. If that solves it, let me know so I can make that change in the official version.

    If it doesn't, it is very likely that you do not have enough RAM to store all of those clips uncompressed at once. You'll either need more RAM or wait for me to figure out how to compress and decompress audio at runtime.
     
  3. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    No, it doesn't work.

    I reckon it's probably the RAM, log at ClipsAndListenersConvertsionSystem line 107 shows that sample size has raise to 233166394.

    Planning separate prefab declaring some other day.

    Btw, there's another wield thing just happened: a clip of load type `Streaming` has none effect at all, entity is there but no sign of sound, `Decompress on Load` is the working though, any thoughts?
     
    DreamingImLatios likes this.
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Sorry about that. But thanks for checking.

    Deduplication is a pain to do with blob asset conversion since there is no pre-generated hash for an AudioClip. I'm currently working on a new feature which may solve this for you, which I am calling "Smart Blobbers". That should land in LSSS in the next week or two. You will likely have to backport it since you aren't on 0.50 yet. Or just having a prefab for each clip will help too. But if you have lots of different clips, then RAM is always going to be the bottleneck until I figure out compression.

    Thanks for bringing this up, as it seems I forgot to mention that in the docs. Decompress on Load is a requirement for Myri, due to this stupid behavior in AudioClip.GetData:
     
    Endlesser likes this.
  5. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Hello everyone!

    As some of you know, I am working on an animation solution called Kinemation that will be compatible with 0.50, and is scheduled to release in the next official Latios Framework feature release 0.5. This has been over half a year in the making and I feel I am close to a real solution. A few people have reached out volunteering to help test these new features.

    I am providing a public alpha version of 0.5 for people to test here. Feel free to try it out and report back any issues you encounter or let me know everything is working (preferably via PM to keep this thread clean)! If you would like to collaborate more closely, PM me.

    The following will be updated with each alpha release:
    Alpha 3: May 1st 2022

    What to Test:

    1. Correct rendering in your project
    2. Correct system ordering and injection behavior in a NetCode project
    3. Correct deformations when modifying bone entity transform components
    4. Correct deformations when Unity Physics Physics Bodies and Joints are added to bones for ragdoll behavior
    5. Correct rendering and deformations on your target hardware
    What to Watch For:

    1) The current Hybrid Renderer's deformation system has a lot of problems. And after not touching it between 0.11 and 0.50, it is clear they don't plan on touching it until 1.0 at the earliest. So Kinemation hijacks the entire render pipeline to replace the deformation system and changes culling to be system-based and customizable. In addition, material properties are updated during culling callbacks and only for chunks which have rendered entities. Please make sure that rendering LODS, lightmaps, probes, ect are all still working as expected. Do note that occlusion culling is not working at this time.

    2) This may come to a surprise to some people as I have never really used or understood NetCode before, and that is still true. However I know enough about custom bootstraps and system manipulation to hopefully have a working compatibility layer which I tested in the samples project.

    3) If you have procedural animation logic, see if it correctly animates a skinned mesh entity.

    4) This might also be a surprise as I don't really like or use Unity Physics either. But I suspect that Kinmation + Myri + Unity Physics + NetCode may become a quite potent combo for the community. With your help testing, I will be able to support it!

    5) There could be some surprise behaviors for normal Hybrid Renderering operations, but for the most part, just make sure the deformation compute shaders behave as expected. You can use the base repo where the alpha is located as a test project. Just build the "Party Dots" scene. In addition, on some mobile platforms, the change to when material properties are uploaded could cause some major stalls. I don't have the hardware to test this, so if you observe this, please let me know.

    How to Test:
    1. Clone or copy this directory into the Packages foler of your project next to manifest.json: https://github.com/Dreaming381/Kine...oduction/Packages/com.latios.latios-framework
    2. Right click in the Assets folder where your code is and create a Latios->Bootstrap->Standard - Injection Workflow (use the NetCode equivalent in a NetCode project)
    3. If testing a skinned mesh, make sure its prefab fully exposes all bones and has an Animator component attached as well. There are currently no custom components to add. The Skinned Mesh should use a shader with a Compute Deformation node.
    Alpha Changelog:
    • Alpha 3
      • Material Properties are uploaded during culling rather than during the HybridRendererSystem update.
      • Compute deform vertex memory is only allocated for visible skinned meshes, drastically reducing VRAM usage. A scene with 100,000 dancers now renders correctly in my tests and is entirely CPU-bound. This change should make skinned mesh LODs viable.
    • Alpha 2
      • Fixed binding bug where target skeletons weren't batched together
      • Updated to the newest DOTS patch release including NetCode fixes

    If you would like to contribute:
    If you have the time, knowledge, and willingness to help out in one of these three areas:
    • Editor import scripts (No DOTS knowledge required)
    • Burst-compatible native plugin bindings
    • GitHub Workflows
    Please PM me!

    One last note:
    So nobody asks, no, animation clips aren't supported in this alpha. Yes they will be in the 0.5 release.
     
    Last edited: May 2, 2022
  6. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    857
    Do you by chance know the status of this bug/is there an issuetracker page for it?
     
  7. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Ticket is still open. No replies from QA. No acknowledgement from Unity on these forums despite mentioning it in several threads. Just silence. It is really frustrating...
     
    thelebaron likes this.
  8. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    Another quick feedback about Myri 0.4.4:

    When instantiate an entity prefab with one shot audio source, the fore part of the beginning(less then 0.1 sec I think) is occasionally missing, sounded like the clip is playback at half way, especially with extreme short audio clip like:

    upload_2022-4-27_17-37-50.png
     

    Attached Files:

  9. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Try adding an AudioSettings to the worldBloackboardEntity and setting the Lookahead Audio Frames to 1. Frame drops at the start of clips usually mean there's a timing issue between the main thread and the DSP thread. What I suggested will usually resolve that issue (but adds a frame of latency to the audio relative to gameplay). If that doesn't help, PM me as I will need more information about your project and usage.
     
    Endlesser likes this.
  10. flagredomega

    flagredomega

    Joined:
    Oct 12, 2017
    Posts:
    12
    Hi, I'm testing Kinemation now. The samples provided run fine. I get around 30fps in the Party scene, 35fps in the Party Dots scene, and 75fps in Party Dots Optimized.

    I'm wondering what the minimum setup to get Kinemation working in a new project is. I made a new URP project, added a gameobject with a skinned mesh renderer (and shaders to support mesh deformation) and set it to convert to entity. In that setup, Unity's hybrid renderer processes and renders mesh deformations correctly.

    Copying Kinemation and Latios Framework from the Kinemation sample project causes the following error when playing in the editor:
    Adding a HybridSkinningToggle component and enabling the hybrid renderer gives this error on play instead:
    That looks to me like some sort of initialization is missing, but I'm not sure what. Please let me know if there's something else I need to do here.
     
  11. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Thanks for reaching out! I realize that I forgot to update this thread with the new binding system update, so I'll go through the complete process here.

    1) Clone the Kinemation prototype repo and checkout the journey_to_production branch.
    2) Open the project and run either Party DOTS or Party DOTS Optimized.
    3) The dancers' colors should be animated. If not, you have the wrong branch.
    4) Copy the framework folder from the Packages folder and paste it into the Packages folder of your custom project.
    5) Add a Latios Bootstrap. Use the Standard, Dreaming, or NetCode variants. Recommended for most similarity with normal Unity is the Standard Injection Workflow.
    6) Add your character prefab to a subscene, prefab reference, or Convert To Entity. The prefab can either have an optimized hierarchy or have all exposed bones. Depending on which you do will determine how you animate the character. Most people will want the fully exposed hierarchy when starting out. SkinnedMeshRenderers need either a ComputeDeform shader graph node or a Linear Blend Skinning node as a custom shader graph material.
    7) Add an Animator component to the prefab to be converted. It should be placed on or an ancestor above the "armature" GameObject. Only the existence matters. No other aspect needs to be configured.
    8) For extra binding customization, you can add a Skeleton Authoring to the GameObject with an Animator, and a Skinned Mesh Authoring for a GameObject with the Skinned Mesh Renderer. If you need more info on how this works and what you can do with it, just ask!
    9) For an exposed skeleton, each bone GameObject is converted to an entity with all the correct components. You simply have to modify the local transform components (rendering reads LocalToWorld). It should be possible to unparent these bones and still get correct rendering for use with Unity Physics ragdolls.
    10) For optimized skeletons, you have to modify the OptimizedLocalToRoot dynamic buffer. There is an OptimizedSkeletonHierarchyBlobReference which provides the hierarchical structure.

    If after doing these steps, you still run into issues with null objects, first check if the DOTS Hierarchy has a World Blackboard Entity. Some projects delete all entities at startup and that is not an entity you want to delete.

    After that, send a bug report with detailed repro steps or a repro project. You can do this via PM or via email.

    And for all of you wondering about animation clips, I am working on that right now. Assuming no frustrating bugs and that the severe weather doesn't knock out my power, I should have that working this week. ;)
     
  12. flagredomega

    flagredomega

    Joined:
    Oct 12, 2017
    Posts:
    12
    Thanks very much! I've followed your instructions, and it seems to be working. I look forward to the full release, I'll probably use it in my next project.

    Using either of the injection bootstraps gives an error, and the explicit minimal bootstrap doesn't seem to convert the gameobject to a skeleton, so I had to use standard explicit bootstrap. Here's the error that the injection bootstraps give:
    That error occurs with a brand new Unity project (just Latios and the hybrid renderer added in the package manager), and just the bootstrapper added, so it's probably pretty easy to replicate, but if not let me know and I can send a project file.
     
  13. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Every time I think I have this bug squashed, it always comes back. :mad:

    Thanks for reporting! It should be fixed now, hopefully. :p

    Also, I'm glad you were able to get it working. Looking forward to see what you do with it!
     
  14. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Latios Framework 0.5 is Officially Here!
    Link

    MechaWalkX10000loopHQ.gif
    This is a feature release targeting Entities 0.50.1. Feature releases contain breaking changes, so please read the Upgrade Guide if you are using [0.4.4]. There have been significant changes to how bootstraps work.

    Overall Highlights
    I had two goals for this release:



      • No surprises compatibility with DOTS projects
      • Bring Kinemation to a public release
    Core Highlights
    There is a new installer-based workflow for bootstraps. All optional features that have automatic side-effects now have installers. That includes Scene Manager, which caused a lot of compatibility issues and used to require hacks. And with that change, I finally can now offer experimental...

    NetCode support!

    I still don't understand how much of it works, but I was able to get the samples working using modified transforms systems and Kinemation's renderer.

    In addition, there's now new bootstrap templates as well as a few others.

    Alright. Enough of that, the other big Core highlight is Smart Blobbers. They offer a way better workflow for creating blob assets during conversion. Authoring MonoBehaviours can request blobs be generated early on during conversion and receive the results later, which turned out to be critical for Kinemation.

    Psyshock Physics Highlights
    Convex colliders are here. And there's experimental support for triangle colliders.

    There's also new debug drawers for colliders. You can tell I had a lot of fights with convex colliders. :oops:

    Myri Audio Highlights
    Myri unfortunately didn't see much in this update. However, it did switch to using Smart Blobbers for conversion would provides automatic deduplication on the input and greatly reduces the amount of RAM neeeded to perform conversion. This was an issue discussed earlier in this thread.

    Kinemation Highlights
    Alright. You all knew this was coming. I'm not going to pretend like you didn't.

    Kinemation is here. And it is certainly something. It has more runtime systems than all the other modules combined, and by a significant margin. It has also been the biggest driver for making the Latios Framework in the first place. I want an animation system that will change the industry. And while this isn't there yet, it is a huge milestone!

    Disclaimers:
    So compared to Unity's old DOTS animation preview, that had a lot of high-level features but was difficult to use and customize. It also suffered some scaling issues.

    Kinemation does not really have a lot of features. Its focus for this first release was performant rendering, a binding workflow that handles challenging use cases, and simplicity of use.

    Kinemation is extremely invasive, in that it replaces much of the Hybrid Renderer. Fortunately, most people may not even notice as the core workflows are preserved. But be warned.

    Also, this first release is Windows only. There's no technical barrier. I just can't compile and test a cross-platform c++ native plugin for other platforms. So I need your help!

    And lastly, there's still a lot of performance left on the table. But I will let you all judge what that actually means.

    Actual Highlights:
    Kinemation properly supports frustum culling skinned meshes using an animation-independent algorithm.

    Kinemation only skins meshes that pass culling.

    Kinemation exposes a public culling API.

    Kinemation skins all mesh instances for all meshes in one compute shader dispatch, so all GPU cores can be activated at once.

    Kinemation only uploads material properties for chunks that have at least one visible entity in a given frame.

    Kinemation supports both Linear Blend Skinning and Compute Deform shaders. Compute Deform is 50% faster than Hybrid Renderer.

    Kinemation supports converting Optimized Game Object hierarchies and will even use this as a signal to form its own optimized hierarchy.

    For fully exposed bones, modifying bone transform components deforms the mesh, just like Game Objects.

    For animation clips, Kinemation uses ACL, a AAA library that ended up being an amazing fit! I have a ton of respect for this library. It really works! Quality is higher than Unity, with far smaller compressed clips. And the whole thing is fast! I'm not even using the optimal path (Unity allocator issue I need to resolve) and it still keeps up with DOTS scales.

    Sampling animation is an immediate API. You can sample a clip at any time from any thread, and do whatever you want with the data.

    Kinemation is conscious of ParentScaleInverse throughout the entire stack. ParentScaleInverse removes unwanted sharing from a parent being non-uniformly scaled. In other words, it is possible to get the same squash-n-stretch behavior of DCCs.

    Kinemation is designed to handle problems like weapon switching and character customization. So if you attempt these sorts of things and run into issues, please reach out!

    What's Next?
    This has been a massive undertaking! And so I'm probably going to take a break from developing new features and instead focusing my efforts at addressing issues that come up and providing support. I'll also be working on some demo content to better showcase the system in action.

    But of course, I would love your feedback. I want to know what aspects you like, what issues you run into, which features on the roadmap you are hoping I prioritize, ect. And if you do anything cool with the framework, don't be afraid to show it off. I love seeing the stuff you all come up with!

    And with that, I want to open up this thread to everyone willing to give this a shot!

    Enjoy the new release!
     
    Last edited: Jun 13, 2022
  15. scottjdaley

    scottjdaley

    Joined:
    Aug 1, 2013
    Posts:
    163
    Wow, what an incredible achievement! Kinemation sounds great and I know a lot of people (myself included) are excited to have a solution for animation in DOTS. I really appreciate all the hard work you have put towards this and sharing it with the community.
     
    mikaelK, DrBoum, bb8_1 and 2 others like this.
  16. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Latios Framework 0.5.1 is out!
    Due to the issues with DOTS 0.51.0, this release remains compatible with 0.50.1. If you are using 0.51.0 and run into issues with the Script Updater, let me know! Packages can be weird sometimes.

    I want to thank everyone who tested out Kinemation this last week and reported issues. As some of you may have figured out, I was quite anxious to get the release out before a collection of events happened (one of which was the release of DOTS 0.51 which I somehow predicted correctly down to the day). As such, I had very limited time to build different test scenarios. Eventually I will have some real-world projects to catch issues like these before releases. But hopefully this bugfix release got rid of most of them.

    Anyways, this test scene works now:
    TestCrew.gif


    While fixing bugs today, I decided to attempt making pose sampling work for optimized skeletons. Pose sampling is significantly faster than bone sampling. However, it requires a full buffer of memory to write to at once. And due to the way Unity's allocators work, you either end up with a bunch of Temp fallback allocations or chew up RAM with World.UpdateAllocator.

    The solution for this is thread-local rewind allocators. But I probably won't be able to implement that until 0.6. However, I did figure out a way to make pose sampling work for optimized skeletons when only a single pose needs to be sampled without blending. I do this by aliasing the dynamic buffer memory and some special in-place transformations.

    Here's 290k bones sampled using SampleBone()
    upload_2022-6-19_1-48-26.png

    And here's those 290k bones sampled using SamplePose()
    upload_2022-6-19_1-47-52.png

    As long as you all help me out by reporting issues and providing feedback, I'll keep finding time to make improvements like this. :D

    Enjoy the release!

    PS - I'm still waiting for someone to send me a gif or video of Kinemation-based animation in their project. ;)
     
    OldMage, rawna, Dechichi01 and 3 others like this.
  17. Dechichi01

    Dechichi01

    Joined:
    Jun 5, 2016
    Posts:
    39
    @DreamingImLatios thanks so much for building this. I've just updated my local project and all bugs that I found have been fixed.

    I am close to finishing the first pass of an Animation FMS API based on Kinamation that I'd be happy to show here (and also would be looking forward to discussing it with you, as I plan to open source it *and* build it to the level of being production ready).

    I'll try to post a sample of it this week.
     
    bb8_1, OldMage, mikaelK and 2 others like this.
  18. OldMage

    OldMage

    Joined:
    Jun 25, 2018
    Posts:
    10
    @DreamingImLatios I'm super excited to use this framework when I have the time!

    I haven't had time to get hands on with it yet though, so sorry if my question was answered somewhere before, but I was wondering if your framework supports out of the box frustum culling for non-deforming mesh geometry?

    I saw that frustum culling was a feature of Kinemation, so I was wondering if there's a version of that feature where a user could see performance gains on a scene that's densely packed with meshes.

    Specifically for my job, I'm trying to make an optimized 3D Model Viewer application where engineers can fly around in 3D Space and look at Technical Models of up to 10+ Million Triangles.
     
  19. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    The normal Hybrid Renderer actually supports frustum culling too, and Kinemation effectively uses a refactored version of the same algorithm with a few key differences.

    Hybrid Renderer
    • Uploads GPU data before culling
    • For linear blend skinning, uploads all skinned matrices and for compute deform, dispatches compute skinning before culling
    • For skinned meshes, uses bounds baked at conversion and does not update them, which can lead to objects not being rendered that should
    Kinemation Renderer
    • Uploads GPU data after culling, taking results into account (which can be faster when there is a lot of dynamic objects off screen)
    • For skinning, GPU resources are allocated and shaders dispatched after culling, leading to huge GPU memory and computational savings
    • For skinned meshes, bounds are computed dynamically independent of animation, making them much more robust
    • The culling pipeline is customizable
    • The culling piepline has a heavy fixed main thread cost I still need to optimize, so if the Hybrid Renderer is sufficient for your exclusively rigid mesh needs, then use that.
     
    OldMage likes this.
  20. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    @DreamingImLatios I am having difficulties using your framework in my project.
    In particular Entities that are created in the OnCreate methods of Systems seem to vanish at some point between their creation and the first Update.
    This breaks quite a lot of my functionality, as well as some Packages I'm using.
    Can you help me track down the issue?

    I have tracked it down to your scene change behaviour.
    The SceneManagerSystem destroys the entities as they are not tagged with DontDestroyOnSceneLoadTag.

    Do you know how to use GetCreatedAndDestroyedEntities ?
    I now need to get the created entities during OnCreate and add the DontDestroyOnSceneLoadTag
     
    Last edited: Jun 23, 2022
    DreamingImLatios likes this.
  21. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Absolutely.

    Which version are you using? Which bootstrap are you using? Do you intend to use scene management or do you want that off?

    In the latest version, scene management is disabled by default in nearly all bootstraps, so I'm a little surprised you are encountering this and would like to know more.
     
  22. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    I am using version 0.5.1, bootstrap is the standard injection with added scene management.

    I intended on using scene management, I like the way you implemented it. But with this issue I might hold off on it
     
    DreamingImLatios likes this.
  23. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Ok. That makes more sense.

    Easiest way to get around this issue is to add the DontDestroyOnSceneChangeTag to all the entities you create in OnCreate(). Also, if these are just singular entities to exchange data between systems, you might want to use worldBlackboardEntity to hold that data instead. That is also safe from scene management behavior.
     
  24. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    That will be interesting when using Unity.Physics: They are doing the same
    But I read what you think of Unity.Physics, doesn't surprise me you didn't find this issue yourself.

    To top it all off, the component they're using for the singleton is internal, so there is no easy way to add the DontDestroyOnSceneChangeTag to it...

    I guess, I'll either have to use the InternalsVisibleTo in a customised Unity.Physics or find a way to use the GetCreatedAndDestroyedEntities method of the EntityManager for it.

    Thanks for your help and the lovely framework ;)
     
    DreamingImLatios likes this.
  25. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Shoot! I knew that they had that singleton, but I didn't realize they made the component type internal. Ugh.

    Alright. I think I got an idea. At the end of the LatiosBootstrap, right before it returns, get the EntityManager from the World and use it to add the DontDestroyOnSceneChangeTag to the UniversalQuery. All the OnCreate calls should have finished by then.
     
  26. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    That's quite elegant, I have written this method:

    Code (CSharp):
    1. public static class MyBootstrapTools
    2. {
    3.     public static BootstrapTools.ComponentSystemBaseSystemHandleUntypedUnion[] InjectSystemsCreatingEntities(
    4.         IReadOnlyList<Type> systems, World world, ComponentSystemGroup defaultGroup = null, IReadOnlyDictionary<Type, Type> groupRemap = null)
    5.     {
    6.         var state = new NativeList<int>(1, Allocator.TempJob);
    7.         var createdEntities = new NativeList<Entity>(Allocator.TempJob);
    8.         var destroyedEntities = new NativeList<Entity>(Allocator.TempJob);
    9.         world.EntityManager.GetCreatedAndDestroyedEntities(state, createdEntities, destroyedEntities);
    10.  
    11.         var ret = BootstrapTools.InjectSystems(systems, world, defaultGroup, groupRemap);
    12.  
    13.         world.EntityManager.GetCreatedAndDestroyedEntities(state, createdEntities, destroyedEntities);
    14.         world.EntityManager.AddComponent<DontDestroyOnSceneChangeTag>(createdEntities);
    15.         state.Dispose();
    16.         createdEntities.Dispose();
    17.         destroyedEntities.Dispose();
    18.  
    19.         return ret;
    20.     }
    21. }
    To get the entities created during system creation that's happening in InjectSystems.

    I guess the result is the same and one can do it either way.
     
    Last edited: Jun 23, 2022
    tmonestudio and DreamingImLatios like this.
  27. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    Hey @DreamingImLatios !
    I tried Kinemation following your documentation and oh boy !
    1570 Skeletons runs at 60fps in the editor and done it was so easy and smooth , GREAT job !
    Capture.PNG
     
  28. Dechichi01

    Dechichi01

    Joined:
    Jun 5, 2016
    Posts:
    39
    Sharing a small milestone on the Animation State Machine tool I'm building.



    Currently it supports:
    • Optimized and non-optimized bones
    • Playing single clip state at different speeds
    • Blending between states
    • Boolean based transitions between states (OR/AND)
    • End time transitions between states
    • 1D Blend Tree
    • Root Motion (with WriteGroup support)
    • Animation Events
    • One Shot animations (playing a single animation that is not on the state machine)
    • Object attachment
    Right now the state machine can only be setup via code (during conversion). Here's the code for setting up the state machine in the example:

    Code (CSharp):
    1.         var blob = clipBlob.Resolve();
    2.  
    3.         //create samplers
    4.         var idleSampler =
    5.             AddSampler(entity, dstManager, blob, 0, new ClipSamplerCreateParams(1, 0));
    6.         var walkSampler =
    7.             AddSampler(entity, dstManager, blob, 1, new ClipSamplerCreateParams(1, 0.2f));
    8.         var runSampler =
    9.             AddSampler(entity, dstManager, blob, 2, new ClipSamplerCreateParams(1, 0.8f));
    10.  
    11.         //Add events
    12.         walkSampler.AddEvent(0.2f, LocomotionAnimationEvents.FootStepEventPtr);
    13.         runSampler.AddEvent(0.1f, LocomotionAnimationEvents.FootStepEvent2Ptr);
    14.  
    15.         //Create 1D Blend Tree state
    16.         var locomotionState = AnimationConversionUtils.AddAnimationState(entity, dstManager, idleSampler.Index,
    17.             runSampler.Index, new AnimationStateCreateParams(AnimationSamplerType.LinearBlend, 0.3f), "Locomotion");
    18.         //Add blend tree parameter
    19.         AddBlendParameter(locomotionState, "Speed");
    20.  
    21.         // Create single clip state
    22.         var jumpState = AddAnimationState_Single(entity, dstManager, blob, 3,
    23.             ClipSamplerCreateParams.Default, AnimationStateCreateParams.DefaultLoop, "Jump");
    24.  
    25.         //Two boolean parameters
    26.         var isJumpingParam = AddParameter<bool>(entity, dstManager, "IsJumping");
    27.         var isFallingParam = AddParameter<bool>(entity, dstManager, "IsFalling");
    28.  
    29.         //Transition from Locomotion -> Jump (both isJumping and isFalling need to be true)
    30.         var transitionGroup = AddTransitionGroup(locomotionState, jumpState);
    31.         AddTransition(transitionGroup, isJumpingParam, true);
    32.         AddTransition(transitionGroup, isFallingParam, true);
    33.      
    34.         //Transition from Jump -> Locomotion when isJumping is false
    35.         AddSingleTransition(jumpState, locomotionState, isJumpingParam, false);
    36.  
    37.         //Create fms
    38.         AddAnimationStateMachine(entity,dstManager,conversionSystem, owner, locomotionState);
    39.  

    Next step is implementing 2D Blend Trees (Directional/Freeform) and a proper editor tool.

    I'm considering open sourcing this tool, so if you think it would be useful for you let me know.
     
    bb8_1, tassarho, laurencew and 9 others like this.
  29. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    It was my goal to design Kinemation such that a tool like this could easily be built on top of this. However...

    You did this in 12 days from the initial Kinemation release?

    My mind is exploding by just how impressive and humbling this is! Amazing job!

    I could list off quite a few reasons why this would be useful for me and others if it was open sourced with a permissive license, even if I or others never actually used it directly. However, I'm obviously biased. :p

    I will provide some insight I have gathered. Leading up to the release of Kinemation, people have asked me about its design and I heard a lot of different opinions of Unity's past four animation systems (Simple, Mecanim, Playables, and their DOTS prototype). Those opinions wildly varied and it became clear there will never be a one-size-fits-all solution when it comes to higher level features. The more solutions like this (or even unlike this) that exist, the better chance one of the solutions will be just what an individual or team needs, days, months, or even years from now.

    Please by all means do what makes the most sense for your goals. I'm in a unique position where open sourcing the Latios Framework made the most sense for me. But do not feel obligated to do the same. Regardless of what you do, I will support your decision and am willing to support you in other ways as well!

    Thanks again for sharing!
     
    OldMage and Occuros like this.
  30. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    I tried this morning the optimized skeletons version and I'm not disappointed ^^

    6.3K skeletons at 60FPS for 34.9M vertices. ( I think if I continue further I will be GPU bound way before the cpu)
    :eek:

    Animation.gif

    By the way DreamImLatios, Lod system works with Kinemation ? I mean LODs not valid for screen are discarded from rendering & animation system ?
     
  31. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Kinda. LODs are evaluated per camera and are considered part of the visibility calculation along with frustum culling, so LODs can reduce skinning operations (especially important for compute deform skinning).

    Animation sampling is up to you because animation could have gameplay consequences. Plus culling reacts to the animation result and consequently needs animation to happen first, which is different from traditional Unity but more robust to procedural animations and other complex use cases.
     
    OldMage and Sylmerria like this.
  32. Dechichi01

    Dechichi01

    Joined:
    Jun 5, 2016
    Posts:
    39
    @DreamingImLatios Thanks so much for the feedback. I've separated the tool into a proper package, and I'll send you the github link to get your thoughts on it.

    Personally I'm more motivated to put a DOTS animation tool out there for the community to use and give feedback to. I've made this tool primarily for the game my team and I are building, and it would not be possible if you hadn't made Kinemation open source. I'd like to continue this chain.
     
    EduardoLauer, bb8_1, OldMage and 4 others like this.
  33. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    Last edited: Jun 30, 2022
  34. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    @Endlesser Latios framework 0.4.4 is only compatible with Unity versions up to 2020.3.25f1. Newer Unity versions require an updated or modified (search the forums for NativeList.AsDeferredJobArray fixes) Collections package.

    If you are starting down the road of updating to newer DOTS, 0.4.5 is compatible and does not have this issue as it is using the updated Collections package. 0.5.0 greatly mitigates the allocator issue you ran into a few posts back. And the 0.5.2 release this weekend will fix a regression with stereo clips.
     
    Endlesser likes this.
  35. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    @DreamingImLatios sorry for bothering again, but it seems like I don't quite understand Psyshock yet, I'm getting this error:
    The system CollisionSystem reads Latios.Psyshock.Collider via BuildCollisionLayerInternal:Part1FromQueryJob but that type was not assigned to the Dependency property.
    To ensure correct behavior of other systems, the job or a dependency must be assigned to the Dependency property before returning from the OnUpdate method.


    OnUpdate looks like this:

    Code (CSharp):
    1. Dependency = Physics.BuildCollisionLayer(dynamicQuery, this).WithSettings(settings).ScheduleParallel(out var dynamicLayer, Allocator.TempJob, Dependency);
    2.  
    3. Dependency = Physics.BuildCollisionLayer(kinematicQuery, this).WithSettings(settings).ScheduleParallel(out var kinematicLayer, Allocator.TempJob, Dependency);
    4.  
    5. Dependency = Physics.FindPairs(staticLayer, dynamicLayer, staticDynamicFindPairs).ScheduleParallel(Dependency);
     
  36. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    One of your queries is missing a
    ComponentType.ReadOnly<Latios.Psyshock.Collider>


    If you don't know how to resolve that, please show your code where you are creating dynamicQuery and kinematicQuery.
     
    Zaphodgame likes this.
  37. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    Code (CSharp):
    1. staticQuery = Fluent.WithAll<PhysicsStaticTag>().PatchQueryForBuildingCollisionLayer().Build();
    2. dynamicQuery = Fluent.WithAll<PhysicsDynamicTag>().WithAll<PhysicsVelocity>().PatchQueryForBuildingCollisionLayer().Build();
    3. kinematicQuery = Fluent.WithAll<PhysicsKinematicTag>().WithAll<PhysicsVelocity>().PatchQueryForBuildingCollisionLayer().Build();
     
  38. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    @DreamingImLatios actually, nevermind.
    The IFindPairsProcessor job I'm passing was throwing exceptions, after commenting out the lines that weren't working I don't get any exceptions.

    I guess that's the usual chain when working with jobs and early out of OnUpate due to errors

    Thanks anyway, keep up the good work
     
  39. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Latios Framework 0.5.3 is out!
    It just keeps getting better!

    What's New
    Support has been awesome lately! And because of that, this release includes bug fixes across all modules. Check the changelogs in the Documentation folder to see all the fixes.

    In addition, this release comes with more improvements to Kinemation. Long story short, I figured out how to do blending of sampled poses using only a single working buffer. That means Optimized Skeletons can do blending with pose sampling, no allocators required. Special thanks to @Dechichi01 for providing an environment to develop this feature quickly!

    Also, I'm now using GitHub Actions to build the native plugin for ACL. There's a tagged release which contains artifacts of not just the compile libraries, but also the debug symbols and human-readable assembly.

    With GitHub Actions comes Linux support. Why Linux? Well, because I have a little bit of familiarity working with it and know what shared objects are supposed to look like. If one of you kind people would like to help me get this working for Mac OS, Android, or iOS, I will gladly take up your offer!

    Also, there's a new Optimization Adventure which I know some of you like reading. It is about Kinemation and some of the madness that went into its architecture. Be warned, it is quite dense.

    What's Next
    My schedule is quite busy for the rest of July, with each weekend getting busier until the final culmination of an annual 48+8 jam (which I'll be using DOTS for :p). I'll still try to address issues and be responsive, but don't expect any exciting new developments or videos in the short term. However, I can at least share my initial plans for 0.6.

    Right now I am looking to improve Psyshock's Collision Layer functionality. That means raycast and collidercast queries against layers, as will as several other advanced features.

    I also plan to start actual development on MachAxle AI.

    And lastly, I'm going to be starting my next open project similar to LSSS, but this one will include assets and feature animated characters. While I don't expect anyone to help, I will definitely be open to any collaborators. Expect more details in August.

    But of course, all of this is subject to change. And you can help me prioritize with:

    The 0.5 Improvement Survey!

    One last thing, please do not be ashamed or feel like you are bothering me by asking questions about the Latios Framework or any random issues with it you encounter. Such questions are valuable to me, regardless of how trivial my answers may seem.

    Enjoy the 0.5.3 release!
     
    Last edited: Jul 4, 2022
    Krajca, Zaphodgame, OldMage and 9 others like this.
  40. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    @DreamingImLatios I'm having difficulties saving the results of a call to FindPairs.
    It seems like the calls to the Execute method of IFindPairsProcessor have no unique index to tell them apart.
    AFAIK in order to write to a NativeStream I need to have unique indices, e.g. IJobFor index is unique for each call to Execute.
    Writing to a ParallelHashMap requires knowing the capacity in advance, which I don't know if that's possible.

    At the moment I'm trying to use FindPairsResult.jobIndex which I would expect to do the job.
    But it's set to the same value inside a for loop here.

    Can you help me with this? Is this non-intended functionality I'm trying to achieve?
     
    DreamingImLatios likes this.
  41. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Unfortunately, FindPairs doesn't know how many pairs each thread will generate. The best it can do is provide a deterministic thread-unique index based on "buckets" in its multibox structure. That's what jobIndex is, and it is sufficient for ECB and friends. You can think of it more like a chunkIndex rather than an entityInQueryIndex.

    Writing to a NativeStream in parallel is not currently supported, as there is no way to terminate a stream for a given jobIndex. Hashmaps can resize if not using ParallelWriter and using FindPairs.ScheduleSingle() or Run().

    I'd like to know a little bit more about your use case to understand why you need the results in another container. Other containers lose the thread safety guarantee FindPairs provides to pairs which makes doing anything else with the result forcibly single-threaded. One thing I am heavily considering is adding a FindPairsResultCache which would save the internal pair indices and allow iterating over them with multiple FindPairsProcessors with the same threading guarantees. Would that help?
     
    Zaphodgame and Occuros like this.
  42. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    Thanks for your reply, basically I am trying to implement some physics collisions myself. For that I need to find all the collisions happening to one entity during one frame.
    Maybe I'm wrong, but I think there is no way of handling the response to these multiple collisions whilst only handling one collision at a time.
    E.g. running against a corner, either the one wall or the other wall writes their resulting response in my array because it's the same index. This results in my character slowly sliding into one of the wall parts.

    I'm not sure if your cache would help with this but I think it might.

    I could also write my results into components with your PhysicsComponentDataFromEntity, I don't know exactly what's best for my use case yet.
     
    Last edited: Jul 19, 2022
    DreamingImLatios likes this.
  43. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    The most surefire approach that would work for you today is to use PhysicsBufferFromEntity.

    For better performance, you could also make two NativeArray<UnsafeList<T>> the size of each CollisionLayer (or just one if you have a single combined CollisionLayer). Clear the arrays on creation, and pass World.UpdateAllocator.ToAllocator to the processor. Then using the body index from the pair results, you can check if the UnsafeList at that index is created, and if not, allocate it with the custom allocator. You don't have to worry about disposing the UnsafeLists when using this technique, as they will be auto disposed after two frames.

    For kinematic bodies like character controllers, it is possible to do things incrementally. https://github.com/Dreaming381/Lati...Code/SubSystems/LocomotionSystem.cs#L218-L260
    There are however two pitfalls with this technique.

    First, in that code sample, I only have a single support plane. I've found cases since making that demo where the character can get stuck on a bunch of spheres due to all of them having too steep of slopes disabling the character's ability to jump, but suspending the character in the air due to being opposing slopes. This can be solved by holding a fixed size buffer of the most relevant contacts. Unity Physics samples use 4 support planes, and I will likely adopt a similar technique in a future project.

    Second, it is possible for the collision to force a character outside of the original projected AABB FindPairs uses, meaning you might miss some collisions. 0.6 will bring layer queries, which will not only solve this problem, but also provide a mechanism for you to process all potential colliders against a character at once, assuming you don't need to write any data to the walls.
     
  44. showwho

    showwho

    Joined:
    Jun 18, 2013
    Posts:
    19
    @DreamingImLatios, hello, i follow the document for Kinemation, but test failed. Can you take me a demo for Kinemation or scripts? Thanks.
     
  45. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Test failed? What do you mean by that? Did you at least get through Part 2 of the Getting Started Guide?

    I don't have a demo project I can easily share at the moment. The project I used to create the gifs is filled with a bunch of debug tooling and prototype hacks. I plan to work on a proper demo and video next month, but my schedule is pretty tight for the remainder of this month.

    I know Dechichi01 has a sample included in his state machine project. I did run into a couple issues at first before I got it to work, but those were probably my fault.
     
    Anthiese likes this.
  46. showwho

    showwho

    Joined:
    Jun 18, 2013
    Posts:
    19
    @DreamingImLatios, Thanks for you reply. Yes, I follow Part 2 of the Getting Started Guide. Maybe i miss something. It great to hear next month you will provide some demo. I will wait for your demo
     
  47. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    Does this work in parallel? It doesn't work for me at the moment.

    Code (CSharp):
    1. if (collisionResponses[bodyIndex].IsCreated)
    2. {
    3.     UnityEngine.Debug.Log("Adding new element");
    4.     collisionResponses[bodyIndex].Add(response);
    5. }
    6. else
    7. {
    8.     UnityEngine.Debug.Log("Creating new list");
    9.     var list = new UnsafeList<float3>(1, allocator) { response };
    10.     collisionResponses[bodyIndex] = list;
    11. }
    I will consider increasing the initial capacity to something like 4, that should improve performance marginally.

    upload_2022-7-20_10-25-19.png
     
    Last edited: Jul 20, 2022
  48. Zaphodgame

    Zaphodgame

    Joined:
    Feb 15, 2022
    Posts:
    13
    Nevermind, my mistake. Of course a NativeArray just returns by value not by reference, should look like this:

    UnityEngine.Debug.Log("Adding new element");
    var list = collisionResponses[bodyIndex];
    collisionResponses[bodyIndex] = list;
     
    DreamingImLatios likes this.
  49. tassarho

    tassarho

    Joined:
    Aug 25, 2019
    Posts:
    75
    I just tried kinematon, very easy to use :) thanks!

    Just to be sur Kinematon does not implement something similar to animation events?
     
  50. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    No it doesn't, but after seeing how DMotion handles them using wrapper Scriptable Objects, I'm thinking I need to at least bake them into clips. It would just be extra data in the blob assets, and not invoke any functions or trigger any event systems (that's up to higher-level solutions like DMotion).

    Currently I am thinking each event would be defined as follows:
    name - Is FixedString64Bytes sufficient? I should I raise that to 128?
    nameHash - int
    parameter - int
    time - float

    And then I would have a utility method that would collect AnimationEvents from a clip and add them to the SkeletonClipConfig with the following mapping:
    functionName -> name (and indirectly nameHash)
    intParameter -> parameter
    time -> time

    I think that should be sufficient for most use cases, since bool, enum, and float can all be encoded in an int.

    Thoughts?