Hey everyone!
EDIT: Further investigation reveals that the material is updating fine - variables edited on the instance of the component attached to the actor just aren’t updating.
I’m working on a character customization system component in C++, and I’m having trouble getting my MIDs to update. I have materials declared in my header like this:
UPROPERTY(BlueprintReadOnly, Category = "Owning Actor")
USkeletalMeshComponent* Mesh;
UPROPERTY(EditDefaultsOnly, Category = "Materials")
UMaterial* HairMaterial;
UPROPERTY(EditDefaultsOnly, Category = "Materials")
UMaterial* SkinMaterial;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Materials")
UMaterial* AlphaMaterial;
UPROPERTY(BlueprintReadOnly, Category = "Materials")
UMaterialInstanceDynamic* Hair;
UPROPERTY(BlueprintReadOnly, Category = "Materials")
UMaterialInstanceDynamic* Skin;
and I’m attempting to set vector and texture parameter values from both C++ and Blueprint. However, any change I try to make to the instance is silently rejected, and the actor I have this component attached to doesn’t update. I’ve tried changing my MID variables from BlueprintReadOnly to BlueprintReadWrite, but that didn’t help.
My source file looks like this. The last two functions are a product of desperation, and they aren’t applying any changes either. The last function contains some debug that should print the updated colour, but only prints out the default value.
// Sets default values for this component's properties
UCharacterCustomizationComponent::UCharacterCustomizationComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
bWantsInitializeComponent = true;
PrimaryComponentTick.bCanEverTick = true;
PrimaryComponentTick.bStartWithTickEnabled = false;
bReplicates = true;
bAutoActivate = true;
// ...
}
// Called when the game starts
void UCharacterCustomizationComponent::InitializeComponent()
{
Super::InitializeComponent();
// ...
}
// Called every frame. Is not enabled by default.
void UCharacterCustomizationComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction )
{
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
// ...
}
void UCharacterCustomizationComponent::PostInitProperties()
{
Super::PostInitProperties();
ACharacter* Character = Cast<ACharacter>(GetOwner());
if (Character)
{
Mesh = Character->GetMesh();
//Apply the skin to all skin elements
Skin = UMaterialInstanceDynamic::Create(SkinMaterial, this);
if (Skin)
{
for (auto Iter(SkinElements.CreateIterator()); Iter; Iter++)
{
Mesh->SetMaterial(*Iter, Skin);
}
}
//Apply the hair to all hair elements
Hair = UMaterialInstanceDynamic::Create(HairMaterial, this);
if (Hair)
{
for (auto Iter(HairElements.CreateIterator()); Iter; Iter++)
{
Mesh->SetMaterial(*Iter, Hair);
}
}
}
//make sure the overriding blueprint sets all of its values proper in this event.
OnSettingsChanged();
}
void UCharacterCustomizationComponent::SetSkinVectorParameter(FName Key, FLinearColor Colour)
{
if (Skin)
{
Skin->SetVectorParameterValue(Key, Colour);
}
}
void UCharacterCustomizationComponent::SetHairVectorParameter(FName Key, FLinearColor Colour)
{
if (Skin)
{
Hair->SetVectorParameterValue(Key, Colour);
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Red, TEXT("stuff"));
FLinearColor Colour2;
Hair->GetVectorParameterValue(Key, Colour2);
GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Yellow, Colour2.ToString());
}
}
}