#How do I use the RenderMeshArray and MeshMaterialInfo component?

1 messages · Page 1 of 1 (latest)

brittle agate
#

I want to swap an entity's mesh at runtime to show different levels of damage as a work around to DOTS not supporting RenderFeatures nor Blendshapes. BUT, I’m having trouble figuring out how to do it. Below are the approaches I've tried so far:

Approach 1: Add the RenderMeshArray component via an Authoring Script

https://paste.mod.gg/fwaiyoflwsmu/2

My first thought was to simply bake RenderMeshArray component. Looking at the video I attached, you can see that the baker does add the meshes to the RenderMeshArray component as I assign them on the authoring script, while in Edit Mode. However, once I hit play the RenderMeshArray goes back down to 1 element. I think what's going on here is that the MeshFilter or MeshRenderer component might be overriding the baker class I made.

Removing the MeshFilter and MeshRenderer from the object and manually adding all of the rendering components is out of the question because I want the ability to visually position the entities rather than using a spawner script.

Approach 2: Add the meshes post-baking via a System

https://paste.mod.gg/fwaiyoflwsmu/3

So my next approach was to add the meshes post-bake via a System. But I get the following error from the system I wrote:

The type 'Unity.Rendering.RenderMeshArray' cannot be used as type parameter 'T' in the generic type or method 'RefRW<T>'. There is no boxing conversion from 'Unity.Rendering.RenderMeshArray' to 'Unity.Entities.IComponentData'.

I'm not really sure what this means, but I'm assuming it has to do with meshes being managed and that I should be using SystemBase rather than ISystem. But if I use SystemBase then I'm not sure how to access the entities to add the meshes to the RenderMeshArray.

lusty roost
#

I'll start by saying I don't know how to do this exactly, but maybe some insights can help. I know there are people who have done this kind of thing. Maybe someone more knowledgeable can chime in later?

  • You can use managed like this in ISystem just fine, you just cannot burst it.
  • RenderMeshArray is a shared component, which is why you cannot use it with RefRW. Also note that since it is a shared component, you should definitely not modify it in a regular query
  • For all the runtime required components, look at RenderMeshUtility.AddComponents.
  • For baking, upon inspecting RenderMeshArray, I find RenderMeshArray.CombineRenderMeshes(List<RenderMeshUnmanaged), which seems to be used during backing. This suggests RenderMeshArray is not used for baking.
  • I guess you know this, but you can use MaterialMeshInfo to change mesh at runtime (if it's in the render mesh array)
brittle agate
#

Hmmm I see~. I don't know much about Shared Components so I'll read up on it tomorrow along with RenderMeshUtility.AddComponents, and RenderMeshArray.CombineRenderMeshes(List<RenderMeshUnmanaged). Thank you for pointing these out! 😁

I did notice the MaterialMeshInfo component but I haven't figured it out yet. I tried to set the mesh and material index to 0 rather than the default -1 as a test. But the index value never changed. I figured it could be a byproduct of the RenderMeshArray not being setup correctly so I decided to focus on this issue first. Here is a test sytem I wrote for it though:

https://paste.mod.gg/rodemjpxketd/4

lusty roost
#

MaterialMeshInfo is used at runtime to say which mesh and material an entity should render with, so this is what you would use to change your mesh

I do create meshes at runtime using this logic, but I instantiate my objects from prefabs that have a mesh renderer. I'm not changing the material. I have no idea how it works internally, so it's maybe not optimal.

var meshID = state.World.GetExistingSystemManaged<EntitiesGraphicsSystem>().RegisterMesh(someRuntimeCreatedMesh);
var mmi = state.EntityManager.GetComponentData<MaterialMeshInfo>(renderEntity);
mmi.MeshID = meshID;
state.EntityManager.SetComponentData(renderBlockEntity, mmi);