That’s exactly how I feel. But I have no idea how to go about getting the material id otherwise. It’s not like I’m creating it or assigning it at any point - it’s part of the prefab. Usually, you’d get it by using its index, but that information is lost in ECS. Custom bakers did cross my mind, but the baking docs are as rudimentary as material overriding. But anyway, that is not the main issue here.
My misunderstanding stuff is quite likely, as I’m still learning ECS, but let me elaborate, as it seems I’m doing a poor job explaining my problem.
If I wanted to move and highlight an Entity with one material, I could do this (ignore small mistakes - untested code):
[BurstCompile]
public partial struct HighlightJob : IJobEntity {
public EntityCommandBuffer.ParallelWriter Buffer;
private void Execute(
[EntityIndexInQuery] int sortKey, Entity entity, in HighlightData data,
TransformAspect aspect) {
aspect.LocalPosition = data.position;
Buffer.SetComponent(sortKey, entity,
new URPMaterialPropertyBaseColor { Value = data.colour, });
}
}
With multiple materials, this doesn’t work, as ECS creates children to stash the materials. It would be nice if you could do something along the lines of:
private void Execute(
[EntityIndexInQuery] int sortKey, Entity entity, in HighlightData data,
in DynamicBuffer<Child> children, TransformAspect aspect) {
aspect.LocalPosition = data.position;
Buffer.SetComponent(sortKey, children[1],
new URPMaterialPropertyBaseColor { Value = data.colour, });
}
Unfortunately, this also does not work, as the order of children is random. So I’m stuck with something like this:
private void Execute(
[EntityIndexInQuery] int sortKey, Entity entity, in HighlightData data,
in DynamicBuffer<Child> children, TransformAspect aspect) {
aspect.LocalPosition = data.position;
for (var i = 0; i < children.Length; i++) {
var info = World.DefaultGameObjectInjectionWorld.EntityManager
.GetComponentData<MaterialMeshInfo>(children[i].Value);
if (!EvalMeshSomehow(info))
continue;
Buffer.SetComponent(sortKey, children[i],
new URPMaterialPropertyBaseColor { Value = data.colour, });
}
}
Which is horrible, and not burstable, or something like this:
private void Execute(
[EntityIndexInQuery] int sortKey, in HighlightData data,
in DynamicBuffer<Child> children, TransformAspect aspect) {
aspect.LocalPosition = data.position;
for (var i = 0; i < children.Length; i++)
Buffer.AddComponent<CheckMeshAndHighlighTag>(sortKey, children[i]);
// Do actual evaluation and assigning in a separate job.
}
}
And I’m obviously not happy with either of the two approaches, even ignoring the fact that I have to mess with material name strings for the evaluation part.