Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Guidance for implementing deformable meshes

Discussion in 'Entity Component System' started by JonBFS, Aug 7, 2020.

  1. JonBFS

    JonBFS

    Joined:
    Feb 25, 2019
    Posts:
    39
    I'm new to ECS but am interested in learning it for the speed performance and data-oriented simplicity for a VR game idea that I have.

    It requires the player to throw meshes at another target mesh and for it to deform from the impact.

    I'm pretty sure that it can be done using a combination of packages that use DOTS such as the hybrid renderer and unity physics. There's samples and leads on the unity physics front for getting collision events, but I haven't found much on deforming meshes and moving vertices around so that I can change how the mesh looks based on impact.

    Are there any links or samples where this is done?
     
  2. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    I've done stuff with dynamic meshes before, and written about it on various posts, eg:

    https://forum.unity.com/threads/draw-generated-meshes-custom-hybrid-renderer.938231/#post-6135044

    In this case, my suggestion would be to not use hybrid renderer, DOTS physics, or ECS at all (unless you're already using it or really passionate about using experimental tech). Just use a regular
    MeshRenderer
    and collider workflow you're used to. Then do something like this:

    1. Get the Mesh you want to modify (eg from the
    sharedMesh
    component of the
    MeshRenderer
    MonoBehaviour.
    2. Call
    MarkDynamic()

    3. Get the existing vertices into a
    NativeArray

    4. On the frame the mesh needs to be deformed, spawn a deformation job with the current deformation status.
    5. In that job, modify vertex positions.
    6. Somewhere late in the frame or even on the next frame,
    Complete
    the job, set data on the mesh, and
    UploadMeshData(false)


    Step 4 and 5 are where you actually want to put the logic. I'd start by getting the framework in place (eg trigger it with a button and have all the vertices move back by a random ammount or something to make sure it works). Once you're satisfied that it's actually working and properly updating the mesh, then start worrying about how you want it to look and where you want to trigger it -- that's the fun part.

    EDIT: The easy way to grab the data is to use the vertices property on the mesh and upload it with https://docs.unity3d.com/ScriptReference/Mesh.SetVertices.html . If performance is a major concern, you'll need to figure out the vertex format and create a struct for it, memcpy the underlying data, modify it, and then upload the mesh data with https://docs.unity3d.com/ScriptReference/Mesh.SetVertexBufferData.html .
     
    Last edited: Aug 7, 2020
  3. JonBFS

    JonBFS

    Joined:
    Feb 25, 2019
    Posts:
    39
    Yes, this is good advice. Going through the thread, I don't understand most terms being thrown around and I would like to iterate on my design rather than fumble through experimental packages.

    I would be more inclined to use ECS if my design required continuously modifying multiple meshes at the same time, but since I plan on only doing this operation once every second or so, I think I can get away with the current rendering system.

    Thanks!
     
  4. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    Hi Jon,

    I was suggesting abandoning DOTS entirely. "Data Oriented Technology Stack" is a nebulous term that includes:
    1. Jobs system - allows you to safely and efficiently run code in a background thread
    2. Burst - Translates a subset of C# code into LLVM, and compiles it for very high performance (I'm skeptical whether it's much faster than CoreCLR, but it's an order of magnitude faster than Mono, and for some reason Unity doesn't want to incorporate CoreCLR)
    3. ECS - An alternate way to arrange data and design your game which leads to better performance.
    4. Hybrid renderer - A way to render the ECS stuff.
    5. Unity Physics - A stateless physics system (that's quite awesome in its own way and can be used without ECS directly), plus some wrappers to integrate it into ECS.
    6. Netcode - new networking APIs; I know nothing about this.
    7. Possibly some upcoming stuff with animation
    In your case, (1) and (2) apply, but you can do them without (3/4/5/6/7). You can absolutely generate many large meshes every frame just by using burst and scheduling the jobs appropriately. The most important part is to do it in a background thread so that you can update your other things while the meshes are being built.

    I'm generating a very large mesh here. It's probably not super relevant to your case, but it's an example of triggering mesh building from a MonoBehaviour: https://gitlab.com/burningmime/easybuilding/-/blob/master/Packages/building/src/jobs/MeshBuilder.cs
     
    Last edited: Aug 7, 2020
  5. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Skipping a bunch of details here but for your case DOTS or even the new job friendly mesh api's are highly unlikely to add any real value. They most certainly will add a ton of complexity. Deforming a small mesh once every few seconds is just not a big hit even on VR if you just do basic stuff right.

    Use the non allocating api's to get/set the mesh data, pool where appropriate, don't do obviously stupid stuff like allocating every frame when you don't have to. Maybe use DrawMesh. Should be fine.
     
    burningmime likes this.