Change Mesh On The Fly
usernameHed opened this issue · comments
Hello. I have a Build() process in my project where I need at one point, to change the current Mesh of the GameObject (and theire is an ElasticDeformable on it. How do I do it correctly without breaking everything ?
`
Deformable deformable = gameObject.GetComponent();
deformable.ChangeMesh(ModelData.Mesh);
deformable.ResetDynamicData();
`
And it work, but then I have a lot of errors: "A Native Collection has not been disposed, resulting in a memory leak. Enable Full StackTraces to get more details."
It seems to work thought, but I don't like those errors :/
My Goal is to "Reset" the ElasticDeformable, then Change the Mesh of the MeshFilter, and then "Enable" Again the ElasticDeformable. One note thought: Doing so while enabling/Disabling the ElasticDeformable Component doesn't seams to work.
I'm not sure what version you're on, but on the latest if you want to change the mesh, you should only need to call deformable.ChangeMesh(someMesh)
However, for the Elastic Deformable, simply swapping the mesh is not enough because you also need to reset the additional position and velocity data used for the elastic calculations. If you don't reset the data it will look like this:
To reset the dynamic data, all you need to call is DisposeData()
followed by AllocateData()
Here's the example script I wrote to test changing meshes at runtime. Let me know if it works for ya!
using Deform;
using UnityEngine;
public class MeshSwapExample : MonoBehaviour
{
[SerializeField] private Deformable deformable;
[SerializeField] private Mesh swapMesh;
[SerializeField] private KeyCode swapKey = KeyCode.Space;
private Mesh to, from;
private void Start()
{
to = swapMesh;
from = deformable.GetOriginalMesh();
}
private void Update()
{
if (deformable == null)
return;
if (Input.GetKeyDown(swapKey))
{
deformable.ChangeMesh(to);
(to, from) = (from, to);
if (deformable is ElasticDeformable elasticDeformable)
{
// You would normally want to call Complete() before disposing/changing the data to finish any running jobs that are using the data,
// but the deformable.ChangeMesh() call above already calls Complete() so it's not necessary in this case:
// elasticDeformable.Complete();
elasticDeformable.DisposeData();
elasticDeformable.AllocateData();
}
}
}
}
Thanks, I will test that! I had found a dirty solution: remove the ElasticDeformable & create a new one :") I know it's sad... but I had to find something :')
I will try that. I suggest to add an Utility function for the future :)
Hmmm I an unable to reproduce this behavior on my end. Do you mind sharing a repro project, or the exact Unity/Deform version + some code I can run that should cause the error?