4.6 previev USkinnedMeshComponent::GetNumMaterials() issue

Hi,
I have few issues with this change:

https://github.com/EpicGames/UnrealEngine/commit/fa1a7542ca2168b5f9b41b297544f677a6860a8d

int32 USkinnedMeshComponent::GetNumMaterials() const
 {
-	return SkeletalMesh ? SkeletalMesh->Materials.Num() : 0;
+	if (Materials.Num() > 0)
+	{
+		return Materials.Num();
+	}
+	else if (SkeletalMesh)
+	{
+		return SkeletalMesh->Materials.Num();
+	}
+
+	return 0;

In pre 4.6 i could do something like this:

HeadMaterialInstances.AddUninitialized(Head->GetNumMaterials());

for (int32 matIdx = 0; matIdx < Head->GetNumMaterials(); matIdx++)
{
	HeadMaterialInstances[matIdx] = Head->CreateAndSetMaterialInstanceDynamic(matIdx);
	if (HeadMaterialInstances[matIdx])
	{
		HeadMaterialInstances[matIdx]->SetScalarParameterValue(Color1Name, Color1Value);
		HeadMaterialInstances[matIdx]->SetScalarParameterValue(Color2Name, Color2Value);
	}

}

For mesh containing 3 materials Head->GetNumMaterials() always returns 3, but in 4.6 after first loop iteration
Head->GetNumMaterials() is returning 1.

Because of this:

 +    if (Materials.Num() > 0)
 +    {
 +        return Materials.Num();
 +    }

Fine I can remember number of materials before loop and use this counter.

int32 NumMaterials = Head->GetNumMaterials();
if (NumMaterials > 0)
{
	HeadMaterialInstances.AddUninitialized(NumMaterials);

    for (int32 matIdx = 0; matIdx < NumMaterials; matIdx++)
	{
		HeadMaterialInstances[matIdx] = Head->CreateAndSetMaterialInstanceDynamic(matIdx);

		if (HeadMaterialInstances[matIdx])
		{
			HeadMaterialInstances[matIdx]->SetScalarParameterValue(Color1Name, Color1Value);
			HeadMaterialInstances[matIdx]->SetScalarParameterValue(Color2Name, Color2Value);
		}

	}
}

Another issue is with meshes placed on map with replaced materials.

If in pre 4.6 someone changeg material on object placed on level everything was fine. But now in 4.6 when I;m trying to change material on the same object, the engine will crash in

AssetSelection.cpp at this assert 
check(OptionalMaterialSlot < MaterialCount);

Because faulty working GetNumMaterials() which should return 3 but it is returning 1,
the OptionalMaterialSlot = 1…

When I commented out

if (Materials.Num() > 0)
{
  return Materials.Num();
}

In USkinnedMeshComponent::GetNumMaterials() everything seems to be alright.

What do you guys think about it?

Best regards

Pierdek

#Solution, Epic Please Address This

The logic behind the new code looks to be that Epic wants to return Skeletal Mesh material count if the component level count is empty for some reason.

However the implementation does not seem to be panning out correctly.

#Solution Code To Try

Pierdek can you try my modified version and see if it

  1. still fulfills Epic’s goals
  2. also fulfills your use case

If so I can make it a pull request or Epic could see this and do it :slight_smile:

int32 USkinnedMeshComponent::GetNumMaterials() const
{
    if (Materials.Num() <= 0 && SkeletalMesh)
    {
       return SkeletalMesh->Materials.Num();
    }
   
	return Materials.Num();
}

#Action Still Required

This is an answer to the question however Epic we really need you to address this issue!

If you want me to submit as a pull request to 4.6 let me know!

#Question

Reviewing my code I have to ask, do you think the Component level Materials count is just not accurate?

Do you get a difference between

MySkinnedComp->SkeletalMesh->Materials.Num()

and

MySkinnedComp->Materials.Num()  //<~~~~ component level

Rama

I cant test your solution, because I can’t revert back my content to 4.5.

My repro steps:

  1. In 4.5 drag and drop some material to destructible actor which contains 3 materials
  2. save content
  3. merge to 4.6
  4. load map with this destructible actor, observe that he has only 1 material
  5. try drop another material on destructible
  6. crash, it is described above;0

This is my goal, simple change material on actor on the level;) this is nothing special.

bump bump

Hey Pierdek -

I was helping another user that you chimed in on, If you have access to the GitHub can you try this two commits and see if it fixes your issue:

https://github.com/EpicGames/UnrealEngine/commit/d4f5004a592b71b4327c10fc6f84fcd3ac468eb8

https://github.com/EpicGames/UnrealEngine/commit/74f6a883acfddbc7407dc939c2a7eec5dc37b55a

Let us know.

Thank You

Eric Ketchum

It won’t compile, because:

Runtime\Landscape\Private\LandscapeSplines.cpp(966): error C2039: 'OverrideMaterials' : is not a member of 'UControlPointMeshComponent'

Engine\Source\Runtime\Landscape\Private\LandscapeSplines.cpp(1545): error C2039: 'OverrideMaterials' : is not a member of 'USplineMeshComponent'

I’m at 4.7.1 now and the problem is solved here;)