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

Bake Cloth Skinned Mesh

Discussion in 'Scripting' started by ColtonKadlecik_VitruviusVR, Feb 13, 2018.

  1. ColtonKadlecik_VitruviusVR

    ColtonKadlecik_VitruviusVR

    Joined:
    Nov 27, 2015
    Posts:
    197
    Hey All,

    In one of our scenes we have a bunch of dead people propped up on spears with cloth hanging down. There is no wind or anything in the scene so I think the cloth can be baked after it is affected by gravity. I have used SkinnedMeshRenderer.BakeMesh before to bake skinned meshes into static meshes, but it does not take into account the cloth. Does anyone know how to convert the Cloth.vertices to mesh.vertices?

    Here is my current approach:
    1. Save starting cloth vertices
    2. Compare distances of all starting vertices to mesh vertices at bake time
    3. If the distance is small, move the new static mesh vertices to the cloth vertices position

    Only issue is, this doesn't work :p Here is a code sample.. I am not getting any "FOUND" logs even with larger distance comparison values

    Any suggestions on how to convert a cloth skinned mesh into a static mesh?

    Cheers,
    Colton

    P.S. Not worried about the speed of the operation, just as long as it works

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. #if UNITY_EDITOR
    5. using UnityEditor;
    6. #endif
    7. using UnityEngine;
    8.  
    9. [RequireComponent(typeof(SkinnedMeshRenderer))]
    10.     public class SkinnedMeshBaker : MonoBehaviour
    11.     {
    12.         public bool BakeOnAwake = true;
    13.         public KeyCode BakeKey = KeyCode.B;
    14.         public string Name;
    15.  
    16.         private SkinnedMeshRenderer _skinnedMesh;
    17.         private Cloth _cloth;
    18.         private Vector3[] _startingClothVerticies = new Vector3[0];
    19.  
    20.         #region Unity LifeCycle
    21.         private void Awake()
    22.         {
    23.             _skinnedMesh = GetComponent<SkinnedMeshRenderer>();
    24.             _cloth = GetComponent<Cloth>();
    25.  
    26.             if (_cloth)
    27.                 _startingClothVerticies = _cloth.vertices;
    28.  
    29.             if (BakeOnAwake)
    30.                 BakeMesh();
    31.         }
    32.  
    33.         private void Update()
    34.         {
    35.             if (!BakeOnAwake)
    36.             {
    37.                 if(Input.GetKeyDown(BakeKey))
    38.                     BakeMesh();
    39.             }
    40.         }
    41.         #endregion
    42.  
    43.         /// <summary>
    44.         /// Bake the skinned mesh into a mesh accounting for cloth component if exists
    45.         /// </summary>
    46.         void BakeMesh()
    47.         {
    48.             var mesh = new Mesh();
    49.  
    50.             _skinnedMesh.BakeMesh(mesh);
    51.  
    52.             if (_cloth)
    53.             {
    54.                 var meshVerts = mesh.vertices;
    55.  
    56.                 // loop through all verticies and compare the distance to that of the original cloth, then move the verticies to the new position
    57.                 for (var i = 0; i < meshVerts.Length; i++)
    58.                 {
    59.                     for(var j = 0; j < _startingClothVerticies.Length; j++)
    60.                     {
    61.                         if(Vector3.Distance(meshVerts[i], _startingClothVerticies[j]) < 0.001f)
    62.                         {
    63.                             Debug.Log("FOUND");
    64.                             meshVerts[i] = _cloth.vertices[j];
    65.                         }
    66.                          
    67.                     }
    68.                 }
    69.  
    70.                 mesh.vertices = meshVerts;
    71.             }
    72.  
    73. #if UNITY_EDITOR
    74.             AssetDatabase.CreateAsset(mesh, "Assets/Models/" + Name + ".asset");
    75.     #endif
    76.         }
     
  2. ColtonKadlecik_VitruviusVR

    ColtonKadlecik_VitruviusVR

    Joined:
    Nov 27, 2015
    Posts:
    197
    My other idea was to save all the cloth verts and load them in at runtime. However, I dont think this will work because as soon as the cloth component is disabled it stops affecting the skinned mesh renderer. Anyone have any other ideas or know how to convert from cloth.vertices to mesh.vertices? There must be some sort of mapping...?