Is "Set Color Parameter Value on Material" supposed to work without a dynamic material instance defined?? (because it does)

Everything I’ve read when searching, states you “must” create a dynamic material instance first, and then set parameters on the DMI.

But the above works perfectly fine, directly on a static or skeletal mesh, without creating any dynamic material instance first.

My question is, does UE5 automatically do it for you when the mesh is a component in that same blueprint? I’ve been using UE since 5.4, and I’ve been doing this for over a year with no problems… yet I’m confused how it’s been working if people claim you have to define a DMI.

Or… is there going to be any weird intermittent problems because I’m not specifically defining a DMI?

Thanks

DMI belike … Copy your material

I can’t tell if you’re making a joke, or trying to say something here?

Yes

if (!DynamicMaterial)
				{
					DynamicMaterial = CreateAndSetMaterialInstanceDynamic(MaterialIndex);
				}
void UMeshComponent::SetColorParameterValueOnMaterials(const FName ParameterName, const FLinearColor ParameterValue)
{
	if (!bEnableMaterialParameterCaching)
	{
		const TArray<UMaterialInterface*> MaterialInterfaces = GetMaterials();
		for (int32 MaterialIndex = 0; MaterialIndex < MaterialInterfaces.Num(); ++MaterialIndex)
		{
			UMaterialInterface* MaterialInterface = MaterialInterfaces[MaterialIndex];
			if (MaterialInterface)
			{
				UMaterialInstanceDynamic* DynamicMaterial = Cast<UMaterialInstanceDynamic>(MaterialInterface);
				if (!DynamicMaterial)
				{
					DynamicMaterial = CreateAndSetMaterialInstanceDynamic(MaterialIndex);
				}
				DynamicMaterial->SetVectorParameterValue(ParameterName, ParameterValue);
			}
		}
	}
	else
	{
		if (bCachedMaterialParameterIndicesAreDirty)
		{
			CacheMaterialParameterNameIndices();
		}

		// Look up material index array according to ParameterName
		if (FMaterialParameterCache* ParameterCache = MaterialParameterCache.Find(ParameterName))
		{
			const TArray<int32>& MaterialIndices = ParameterCache->VectorParameterMaterialIndices;
			// Loop over all the material indices and update set the parameter value on the corresponding materials		
			for (int32 MaterialIndex : MaterialIndices)
			{
				UMaterialInterface* MaterialInterface = GetMaterial(MaterialIndex);
				if (MaterialInterface)
				{
					UMaterialInstanceDynamic* DynamicMaterial = Cast<UMaterialInstanceDynamic>(MaterialInterface);
					if (!DynamicMaterial)
					{
						DynamicMaterial = CreateAndSetMaterialInstanceDynamic(MaterialIndex);
					}
					DynamicMaterial->SetVectorParameterValue(ParameterName, ParameterValue);
				}
			}
		}
	}
}

That node will create a Dynamic Material Instance and assign it to the mesh.
Other nodes like Set Vector Parameter Value will not do this. That’s why tutorials say you must create a DMI first and then do your parameter work on it.

If you use this mesh node, it will still work because it creates the DMI and sets it on the mesh for you however, if you later try to use Set Vector Parameter Value, it won’t work directly because you don’t have a reference to that instance. From Blueprint’s perspective, you only have a Material Interface reference, while the mesh is actually holding a Material Instance Dynamic internally.

What you need to do is get the material from the mesh and cast it to a Dynamic Material Instance before setting parameters on it. Since that node anyway needs a DMI reference.

Thank you for such an excellent and thorough explanation!

I tried scalar parameter (from the mesh), and it seems to work also. I haven’t tested vector because I don’t use it. It looks like there’s only 3 direct parameter functions from the mesh itself, and other parameters are only available from the DMI itself.

I tried your suggestion of casting to a DMI, and setting a texture parameter and that works too!

As long as this method is “safe” to use, it saves having to deal with managing your own DMI reference.

Thanks again!!

1 Like