[Beginner] Change material color in c++

Hey all, I am new to Unreal engine, and I come from the Unity world but trying to just get my feet wet here. Something simple I figured would be to, on key press, change the material base color on a sphere from white to red. This turns out to be far more complicated than I expected.

I created a new C++ class that inherits from AActor called “TriggeredActor”. In my Settings, I setup an Input called “Trigger” and set it to the K key. Finally on the Input component of the Actor I set Input Auto Receive Input to Player 0. The on screen message from the Trig() method displays with no issue the correct name of the material, but the last line for SetVectorParameterValue causes everything to just close. As there are no issues when I comment out that line.

void ATriggeredActor::BeginPlay()
{
	Super::BeginPlay();
	InputComponent->BindAction("Trigger", IE_Pressed, this, &ATriggeredActor::Trig);
}

void ATriggeredActor::Trig()
{
	UStaticMeshComponent* sphere = this->FindComponentByClass<UStaticMeshComponent>();
	sphere->SetMobility(EComponentMobility::Movable);

	UMaterialInstanceDynamic* material = (UMaterialInstanceDynamic*) sphere->GetMaterial(0);

	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, material->GetName());

	material->SetVectorParameterValue(FName(TEXT("BaseColor")), FLinearColor(0.9f, 0.1f, 0.1f));
}

This is a general combination of things that I’ve found from around the internet, this isn’t a popular topic I guess.

I know this isn’t Unity so can’t compare but this would be something like:

void Update()
{
    if(Input.GetKeyDown(KeyCode.K))
    {
        Renderer renderer = GetComponent<Renderer>();
        renderer.material.SetColor("_Color", Color.red);
    }
}

Thanks for any help you guys can give.

I’m not sure if you are allowed to cast your MID like that. Instead of

UMaterialInstanceDynamic* material = (UMaterialInstanceDynamic*) sphere->GetMaterial(0);

I would use

UMaterialInstanceDynamic* material = UMaterialInstanceDynamic::Create(sphere->GetMaterial(0), NULL);

Also it’s weird to see that Input Binding is handled in BeginPlay, never saw that before. Usually it’s placed in the constructor. Same for the UMaterialInstanceDynamic pointer which I also usually define in the constructor. Furthermore, is there any reason why you included the SetMobility function, because it should work without it.

The SetMobility was because I had read somewhere that static objects like a sphere couldn’t be changed without it as they were considered “terrain”-like features. This may have been for an older version of UE4.

Putting the Input in the constructor actually seems to break the game? In that the same line in the constructor crashes the editor. But putting it in the BeginPlay works.

I was able to get it working, thanks!

Sorry, I mean you want to override the specific function like so:

virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

That’s where Input is usually specified.