I have a piece of cloth in my game and I want tot extract the vertex position in each frame. However the numbers in the list do not change. How can I update these positions? In my code I try to access the mesh component of the cloth then extract the vertex positions but it only shows the initial positions and when I hit start the list won’t get updated.
public Vector3[] clothMeshVerts;
public int numOfVerts;
Vector3[] normals;
public int[] trianlges;
SkinnedMeshRenderer smr;
void Start()
{
smr = GetComponent<SkinnedMeshRenderer>();
}
void Update()
{
clothMeshVerts = smr.sharedMesh.vertices;
numOfVerts = smr.sharedMesh.vertexCount;
}
In the past there was no way to access the current state of a SkinnedMeshRenderer as the skinning happens either on the GPU or in the engine’s core. Of course the sharedMesh it the “unskinned” Mesh or the “source” Mesh.
They now added a way to access the current state of the skinned mesh. You just have to use BakeMesh of your SkinnedMeshRenderer and pass a temp Mesh object which will be “filled” with the current snapshot of the skinned mesh.
Since you want to access the data every frame you might want to re-use that temp Mesh, so don’t create a new one each frame. If you do create a new Mesh, keep in mind that the old one need to be Destroy()-ed or it will hang around in memory and cause a memory leak.
edit
Ahh, ok that’s just another “oddity” of how Unity implements certain things ^^. It seems that BakeMesh doesn’t work with cloth objects. However the Cloth component itself has a “vertices” property which return the current “skinned” vertex positions. I quickly created this script and used a standard plane mesh and it works as intended:
using UnityEngine;
public class ViewClothMesh : MonoBehaviour
{
Cloth cloth;
int[] tris;
void Start ()
{
cloth = GetComponent<Cloth>();
Mesh mesh = GetComponent<SkinnedMeshRenderer>().sharedMesh;
tris = mesh.triangles;
}
void Update ()
{
var verts = cloth.vertices;
for(int i = 0; i < tris.Length; i+=3)
{
var v1 = transform.TransformPoint(verts[tris[i ]]);
var v2 = transform.TransformPoint(verts[tris[i + 1]]);
var v3 = transform.TransformPoint(verts[tris[i + 2]]);
Debug.DrawLine(v1, v2);
Debug.DrawLine(v2, v3);
Debug.DrawLine(v3, v1);
}
}
}
ps: the Cloth component also has a “normals” property in case you need the skinned normals as well.