Search Unity

Question Runtime spawn entity with SkinnedMeshRenderer (entities.graphics@1.0)

Discussion in 'Graphics for ECS' started by jes_, Nov 13, 2022.

  1. jes_

    jes_

    Joined:
    Jun 9, 2017
    Posts:
    1
    I try spawn entity with SMR during rutime, but it has no effect

    Code (CSharp):
    1. public class SpawnSkinnedEntity : MonoBehaviour
    2. {
    3.     public SkinnedMeshRenderer skinnedMeshRenderer;
    4.  
    5.     private void Start()
    6.     {
    7.         var world = World.DefaultGameObjectInjectionWorld;
    8.         var entityManager = world.EntityManager;
    9.  
    10.         var entity = entityManager.CreateEntity();
    11.  
    12.         //Add components
    13.  
    14.         var renderMeshDescription = new RenderMeshDescription(UnityEngine.Rendering.ShadowCastingMode.Off);
    15.  
    16.         var renderMeshArray = new RenderMeshArray(
    17.             new Material[] { skinnedMeshRenderer.sharedMaterial },
    18.             new Mesh[] { skinnedMeshRenderer.sharedMesh }
    19.          );
    20.  
    21.         var materialMeshInfo = MaterialMeshInfo.FromRenderMeshArrayIndices(0, 0, 0);
    22.  
    23.         RenderMeshUtility.AddComponents(
    24.            entity,
    25.            entityManager,
    26.            renderMeshDescription,
    27.            renderMeshArray,
    28.            materialMeshInfo);
    29.  
    30.         entityManager.AddComponentData<LocalToWorld>(entity, new LocalToWorld()
    31.         {
    32.             Value = skinnedMeshRenderer.transform.localToWorldMatrix
    33.         });
    34.  
    35.         var skinMatrices = entityManager.AddBuffer<SkinMatrix>(entity);
    36.  
    37.         //Compute skin matrices
    38.  
    39.         skinMatrices.ResizeUninitialized(skinnedMeshRenderer.bones.Length);
    40.  
    41.         var rootMatrix = skinnedMeshRenderer.rootBone.localToWorldMatrix.inverse;
    42.  
    43.         for (int i = 0; i < skinnedMeshRenderer.bones.Length; ++i)
    44.         {
    45.             if (skinnedMeshRenderer.bones[i] == null)
    46.                 continue;
    47.  
    48.             var bindPose = skinnedMeshRenderer.sharedMesh.bindposes[i];
    49.             var boneMatRootSpace = math.mul(rootMatrix, skinnedMeshRenderer.bones[i].localToWorldMatrix);
    50.             var skinMatRootSpace = math.mul(boneMatRootSpace, bindPose);
    51.  
    52.             skinMatrices[i] = new SkinMatrix
    53.             {
    54.                 Value = new float3x4(skinMatRootSpace.c0.xyz, skinMatRootSpace.c1.xyz, skinMatRootSpace.c2.xyz,
    55.                     skinMatRootSpace.c3.xyz)
    56.             };
    57.         }
    58.  
    59.     }
    60. }

    What i missing? Or currently is only way it's baking?

    One solution i've found, it's change package source code to make DeformedEntity component public and add it to entity, because PushMeshDataSystem need it to add missing components to entity

    Code (CSharp):
    1. entityManager.AddComponentData<DeformedEntity>(entity, new DeformedEntity()
    2. {
    3.    Value = entity
    4. });
     
  2. Jebtor

    Jebtor

    Unity Technologies

    Joined:
    Apr 18, 2018
    Posts:
    115
    The supported path at the moment is through baking. The setup for Deformed Entities is rather involved. A deformed entity is made up out of multiple entities - as a SkinnedMeshRenderer is converted into multiple entities (similar to MeshRenderers with multiple sub-meshes). Furthermore, there are important subtilties with regards to RenderBounds and the root bone to consider.

    We have not exposed any API yet as components and systems very likely will change. Note that the deformations solution in Entities Graphics comes with a disclaimer.