Download

How to change foliage materials in runtime?

I’m trying to figure out a way to change the materials of foliage assets in runtime, and I feel like I’m almost there, but it’s not quite working.

Here is the code I’m using:


void AMaterialSwitcher::SwitchFoliageMaterials()
{
    // Only run if SwitchMaterial (UMaterial Interface) has been set
    if (SwitchMaterial)
    {
        // Create Material Instance Dynamic
        MID_SwitchMaterial = UMaterialInstanceDynamic::Create(SwitchMaterial, this);

        // Iterate through foliage actors
        for (TActorIterator<AInstancedFoliageActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
        {
            AInstancedFoliageActor* FoliageMesh = *ActorItr;

            // Iterate through meshes
            for (auto& MeshPair : FoliageMesh->FoliageMeshes)
            {
                // Get mesh component
                const FFoliageMeshInfo& MeshInfo = *MeshPair.Value;
                UHierarchicalInstancedStaticMeshComponent* MeshComponent = MeshInfo.Component;

                // Iterate through materials
                int32 MaterialsCount = MeshComponent->GetNumMaterials();
                for (int32 MaterialIndex = 0; MaterialIndex < MaterialsCount; MaterialIndex++)
                {
                    // Set material to alternative material
                    MeshComponent->SetMaterial(MaterialIndex, MID_SwitchMaterial);
                }
            }
        }
    }
}

When this function is used, it strips out the old materials, but just ends up with the default null material, it doesn’t apply the intended “Switch material”. Here’s a before and after image:

I have tried using UMaterial, UMaterialInterface and UMaterialInstanceDynamic, but with the same result. Is there some fundamental reason why I cannot apply a new material to the foliage instances?

UPDATE

Nevermind, I figured it out as soon as I posted the question - simply needed to set ‘Usage->Used with Instanced Static Meshes’ on the material. All good now.