ue5 小知识点 UStaticMeshComponent的材质 set get

void UMeshComponent::SetMaterial(int32 ElementIndex, UMaterialInterface* Material)
{
	if (ElementIndex >= 0)
	{
		if (OverrideMaterials.IsValidIndex(ElementIndex) && (OverrideMaterials[ElementIndex] == Material))
		{
			// Do nothing, the material is already set
		}
		else
		{
			// Grow the array if the new index is too large
			if (OverrideMaterials.Num() <= ElementIndex)
			{
				OverrideMaterials.AddZeroed(ElementIndex + 1 - OverrideMaterials.Num());
			}
			
			// Check if we are setting a dynamic instance of the original material, or replacing a nullptr material  (if not we should dirty the material parameter name cache)
			if (Material != nullptr)
			{
				UMaterialInstanceDynamic* DynamicMaterial = Cast<UMaterialInstanceDynamic>(Material);
				if (!((DynamicMaterial != nullptr && DynamicMaterial->Parent == OverrideMaterials[ElementIndex]) || OverrideMaterials[ElementIndex] == nullptr))
				{
					// Mark cached material parameter names dirty
					MarkCachedMaterialParameterNameIndicesDirty();
				}
			}	

			// Set the material and invalidate things
			OverrideMaterials[ElementIndex] = Material;
			MarkRenderStateDirty();			
			if (Material)
			{
				Material->AddToCluster(this, true);
			}

			FBodyInstance* BodyInst = GetBodyInstance();
			if (BodyInst && BodyInst->IsValidBodyInstance())
			{
				BodyInst->UpdatePhysicalMaterials();
			}

#if WITH_EDITOR
			// Static Lighting is updated when compilation finishes
			if (!IsCompiling())
			{
				FStaticLightingSystemInterface::OnPrimitiveComponentUnregistered.Broadcast(this);
				if (HasValidSettingsForStaticLighting(false))
				{
					FStaticLightingSystemInterface::OnPrimitiveComponentRegistered.Broadcast(this);
				}
			}
#endif
		}
	}
}

 set材质调用的是父亲的setmaterial方法 你会发现set的材质会保存在一个叫OverrideMaterials[ElementIndex] = Material;

数组中。

UMaterialInterface* UStaticMeshComponent::GetMaterial(int32 MaterialIndex) const
{
	// If we have a base materials array, use that
	if(OverrideMaterials.IsValidIndex(MaterialIndex) && OverrideMaterials[MaterialIndex])
	{
		return OverrideMaterials[MaterialIndex];
	}
	// Otherwise get from static mesh
	else
	{
		return GetStaticMesh() ? GetStaticMesh()->GetMaterial(MaterialIndex) : nullptr;
	}
}

get的时候 先从OverrideMaterials中拿  没有的话 再从mesh中拿

总结 所以存取都会从OverrideMaterials中拿

但是要想获得材质的数量 就 跟OverrideMaterials 没关系了


int32 UStaticMeshComponent::GetNumMaterials() const
{
	// @note : you don't have to consider Materials.Num()
	// that only counts if overridden and it can't be more than GetStaticMesh()->Materials. 
	if(GetStaticMesh())
	{
		return GetStaticMesh()->GetStaticMaterials().Num();
	}
	else
	{
		return 0;
	}
}

获得材质的数量是直接从mesh上拿的

如果 你 通过数量然后遍历

int32 num = GetNumMaterials();

for(num)

{

        GetMaterial(i);

}

这样是错误的;

所以要用到这个方法

int32 UMeshComponent::GetNumOverrideMaterials() const
{
	return OverrideMaterials.Num();
}

这样得到的数量就正确了

所以 UStaticMeshComponent的set get 和 它里面的staticmesh 的材质 是 独立的两套。

猜你喜欢

转载自blog.csdn.net/opk8848/article/details/126622862