Color interpolation doesnt work on tick

Hey, everyone!
I have a problem :smiley:
I’m doing sky’s color and light intensity interpolation in a tick function.

	float secFraction = 1.f / DeltaTime;
	
	currentLight = SkyLightComp->Intensity;
	float tempLight = ( differenceLight / secFraction ) + currentLight;
	SkyLightComp->SetIntensity( tempLight );
	
	currentColor = SkyLightComp->LightColor;
	tempColor.R = ( differenceColor.R / secFraction ) + currentColor.R;
	tempColor.G = ( differenceColor.G / secFraction ) + currentColor.G;
	tempColor.B = ( differenceColor.B / secFraction ) + currentColor.B;
	tempColor.A = ( differenceColor.A / secFraction ) + currentColor.A;
	SkyLightComp->SetLightColor( tempColor );

This is the best I could come up with to interpolate over a second
Now, the thing is, light interpolation works fine, but the color behaves in a strange way.
It interpolates fine when transitioning from certain curve point to another.
But when it tries other points, nothing happens, unless i move cursor from PIE viewport window, so viewport game fps is decreased, only then it works (and if I set 30 fps in the settings).
And, again, it works just fine when transitioning at other curve points.
There may be smtg I’m missing or messed up. But, in any case, I find such behaviour strange.
I’m using 4.27 version, if that matters.
Video Example

Try the kismet library. They already have a function for color lerping

Hm, haven’t tried that specific one yet, thanks.

Worth mentioning:
tempColor = FMath::CInterpTo( currentColor, targetColor, DeltaTime, 1 );
also doesnt work, unless the frame rate is set to 30, or the interp speed is set to 2 or higher with 60 fps.

Try casting the 1 to a float. It will screw up the calculations as an int, or use 1.0f

Definition:

static FLinearColor CInterpTo
(
    const FLinearColor & Current,
    const FLinearColor & Target,
    float DeltaTime,
    float InterpSpeed
) 

I’m new to c++, don’t know how to cast properly, so I’ve tried these options:
(float)(1)
static_cast< float >(1)
1.0f
Neither fixed the issue with that FMath::CInterpTo.

tempColor = FMath::CInterpTo( currentColor, targetColor, DeltaTime, 1.0f);
should work. I’m guessing this is in the tick function and you are passing in the delta time?

Yep, exactly.

I know it should work, but it doesnt :laughing:

FLinearColor::LerpUsingHSV works.
But docs says

This can give better results than a normal lerp, but is much more expensive.

I’d prefer to avoid heavy things in ticks.
And I initially avoided lerps, coz I wanted the interpolation to take an exact amount of time.
Also, it doesn’t work with lerp alpha = 0.02 and lower.

Ok so looking at the debug info it kept reverting to the source color. You need to override the source with the output from the temp color.
Normally in timeline lerps you don’t change one of the lerp parameters at runtime but here during tick it seems to be necessary.

Example actor that lerps successfully between two set colors at a certain speed.

Header

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ColorChanger.generated.h"

UCLASS()
class YOUR_API AColorChanger : public AActor
{
	GENERATED_BODY()
	
public:	

	AColorChanger();

protected:

	virtual void BeginPlay() override;


public:	

	virtual void Tick(float DeltaTime) override;

	UPROPERTY(EditAnywhere,BlueprintReadWrite)
	FLinearColor SourceColor;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FLinearColor TargetColor;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float timeToChange = 1.0f;

	UPROPERTY(EditAnywhere, BlueprintReadOnly)
	FLinearColor tempColor;
};

cpp

#include "ColorChanger.h"
#include "Math/UnrealMathUtility.h" 


AColorChanger::AColorChanger()
{

	PrimaryActorTick.bCanEverTick = true;

}

void AColorChanger::BeginPlay()
{
	Super::BeginPlay();
	tempColor = SourceColor;
}

// Called every frame
void AColorChanger::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
		
	tempColor = FMath::CInterpTo(tempColor, TargetColor, GetWorld()->DeltaTimeSeconds , timeToChange);
	GEngine->AddOnScreenDebugMessage(1, 1, FColor::Cyan, tempColor.ToString()); // for debuging
}

That worked, thanks a lot! :smiley:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.