UnityECS: How to change material color of a single entity in SystemBase's OnUpdate among a lot of similar objects?

Hi there, I use Unity for a long time, but I’m new to ECS.

I have created a SystemBase to change the color of some entities spawned but not all of them. I want to highlight a sub set of my entities.

I created this SystemBase. It changes the color, but of all of entities that shares the same material. Is there a way to create a new temporary material just for a single entity and reassign to it in order to chante just that color?

Thanks at advance. Here is my code:

    [UpdateAfter(typeof(CityStageSpawnSystem))]
    public partial class ApplyColorSystem : SystemBase
    {
        protected override void OnCreate()
        {
        }

        protected override void OnUpdate()
        {
            Entities.ForEach((ref Entity entity, in ChangeColorComponent colorComponent, in RenderMeshArray renderMeshArray, in MaterialMeshInfo materialMeshInfo) =>
            {
                if(colorComponent.changeIt) {
                    var material = renderMeshArray.GetMaterial(materialMeshInfo);
                    material.color = new UnityEngine.Color(colorComponent.NewColor.x, colorComponent.NewColor.y, colorComponent.NewColor.z, colorComponent.NewColor.w);
                }
            })
            .WithoutBurst().Run();
        }
    }

There’s a concept in Entities Graphics called “Material Property Overrides” which allow you to specify specific material properties as IComponentData. Here’s a link which will serve as a starting point regarding this feature. Material overrides | Entities Graphics | 1.3.0-pre.4

2 Likes

Thank you very much! It helped me a lot!

And to help more people, I going to show my new SystemBase.OnUpdate. It uses now URLMaterialPropertyBaseColor. It’s very rough, but it’s just a POC.

        protected override void OnUpdate()
        {
            Entities.ForEach((ref URPMaterialPropertyBaseColor materialPropertyBaseColor) =>
            {
                i++;
                if (i % 2 == 0)
                {
                    materialPropertyBaseColor.Value = new float4(3, 0, 0, 1);
                }
                else
                {
                    materialPropertyBaseColor.Value = new float4(0, 2, 0, 1);
                }
            })
            .WithoutBurst().Run();
        }
1 Like