[Paper2D / PaperZD / C++ ] Changing SpriteColor through C++ does not update the Sprite at runtime

Hi!

I’m trying to make a HealthComponent that makes the owner (APaperZDCharacter) blink whenever they’re taking damage, like invincible frames.

In my HealthComponent, that is attached to the character, I have this block of code in the TickComponent function:

	if(bInInvincibleFrame)
	{
		/* Show the current sprite color */
		UE_LOG(LogTemp, Display, TEXT("Sprite color is %s"), *MyCharacter->GetSprite()->GetSpriteColor().ToString());

		if(InvincibleNextChange < 0)
		{
			/* Time to update the sprite */
			UE_LOG(LogTemp, Display, TEXT("TickComponent: InvincibleNextChange=%f InvincibleLeft=%f"), InvincibleNextChange, InvincibleLeft);

			if(InvincibleLeft <= 0)
			{
				/* Make sprite visible because this is the last blink */
				MyCharacter->GetSprite()->SetSpriteColor(FLinearColor::White);
				UE_LOG(LogTemp, Display, TEXT("Sprite color reset to %s"), *MyCharacter->GetSprite()->GetSpriteColor().ToString());

				/* Reset variables */
				InvincibleNextChange = 0;
				bInInvincibleFrame = false;
				InvincibleLeft = 0;
				return;
			}

			/* Toggle the color */
			MyCharacter->GetSprite()->SetSpriteColor( (MyCharacter->GetSprite()->GetSpriteColor() == FLinearColor::White ? FLinearColor::Red : FLinearColor::White) );
			/* Show the new color for debug */
			UE_LOG(LogTemp, Display, TEXT("Sprite color set to %s"), *MyCharacter->GetSprite()->GetSpriteColor().ToString());

			/* Next blink in 0.1 sec */
			InvincibleNextChange = 0.1;
		}
		
		/* Decrease timers */
		InvincibleNextChange -= DeltaTime;
		InvincibleLeft -= DeltaTime;
	}

Accoriding to the logs, it executes as it should:

// First call (White)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
TickComponent: InvincibleNextChange=-1.000000 InvincibleLeft=1.000000
// Changed to red
Sprite color set to (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
TickComponent: InvincibleNextChange=-0.000001 InvincibleLeft=0.899999
// Changed to white
Sprite color set to (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
TickComponent: InvincibleNextChange=-0.000001 InvincibleLeft=0.799998
// Changed to red
Sprite color set to (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
Sprite color is (R=1.000000,G=0.000000,B=0.000000,A=1.000000)
TickComponent: InvincibleNextChange=-0.000001 InvincibleLeft=0.699997
// Changed to white
Sprite color set to (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
Sprite color is (R=1.000000,G=1.000000,B=1.000000,A=1.000000)
TickComponent: InvincibleNextChange=-0.000001 InvincibleLeft=-0.000009
// Reset to white
Sprite color reset to (R=1.000000,G=1.000000,B=1.000000,A=1.000000)

As you can see, it changes the color to red and GetSpriteColor() returns red, but it does not update in the editor when playing.

I’ve tried changing the mobility to static and back to movable (saw it in another thread).

The odd part is, if I pause PIE while the sprite should be red, and then stop PIE and select my enemys “Sprite” component, it is set to White but there is a “Restore to default value”-arrow icon, which if pressed reverts the color to red (or whatever color it was when I stopped PIE).

Does anyone have any ideas? Everything else works on the enemy (movement, different animations through the PaperZD statemachine etc).
I’ve also tried changing the sprites visiblity using GetSprite()->SetVisiblity(false) but it acts the same. It sets the value, but the sprite isn’t changed.

Thanks in advance.