How can I set a UNiagaraDataInterfaceColorCurve from a color curve asset?

I’m experimenting with Niagara, hoping to make a damage numbers particle effect that will normally use an all white color curve scaled by a user parameter to indicate the severity of the damage, and when a critical hit occurs it will instead use a rainbow gradient color curve. I couldn’t find a way within Niagara module scripting to conditionally choose one color curve vs. another, and from what I’ve read this is because significant conditional branches have a heavy impact on code intended to run on the GPU (HLSL generated by Niagara).

Instead, I’m trying to set the color curve to use as a Niagara User parameter in C++ and then only the color scale vector changes based on whether or not the damage represents a critical hit (which can be achieved with the selector node). The problem I’m having is that the color curve User parameter is apparently not getting set properly; regardless of the curve I set it to in C++, the particle system uses the default value I provided in the Niagara particle editor for the color curve User parameter. If I unset the default, then the particles become transparent (presumably because the default color curve value is now all zeroes).

Here’s the color curve asset loading code:

FString ColorCurvePath = TEXT("/Game/Ryddelmyst_Assets/Textures/");
        if (IsCrit)
        {
            ColorCurvePath += TEXT("RainbowRoadColorCurve");
        }
        else
        {
            ColorCurvePath += TEXT("WhiteColorCurve");
        }
        UCurveLinearColor* ColorCurveAsset = LoadObject<UCurveLinearColor>
        (
            nullptr,
            *ColorCurvePath,
            nullptr,
            LOAD_None,
            nullptr
        );

I wasn’t 100% certain that UCurveLineraColor is the class I want to represent an asset created in the content browser via Right Click → Miscellaneous → Curve → CurveLinearColor, but it looks about right and gives the FRichCurve curve data that UNiagaraDataInterfaceColorCurve seems to want.

I’m trying to set the UNiagaraDataInterfaceColorCurve as follows:

UNiagaraDataInterface* DataInterfaceForDamageColorCurve = UNiagaraFunctionLibrary::GetDataInterface(UNiagaraDataInterface::StaticClass(), FloatingNumbersFX_Component, FName{ TEXT("DamageColorCurve") });
        if (DataInterfaceForDamageColorCurve)
        {
            if (const auto DataInterfaceColorCurve = Cast<UNiagaraDataInterfaceColorCurve>(DataInterfaceForDamageColorCurve))
            {
                DataInterfaceColorCurve->RedCurve = ColorCurveAsset->FloatCurves[0];
                DataInterfaceColorCurve->GreenCurve = ColorCurveAsset->FloatCurves[1];
                DataInterfaceColorCurve->BlueCurve = ColorCurveAsset->FloatCurves[2];
                DataInterfaceColorCurve->AlphaCurve = ColorCurveAsset->FloatCurves[3];
            }
        }

I’ve verified that the variable ColorCurveAsset is non-null after load and that its Keys[0].Value and Keys[0].Time match the asset configuration, so presumably the load operation succeeded. The question then is how should I actually set the color channel curves in the UNiagaraDataInterfaceColorCurve object? The best approach I could see from the API was to set each channel curve individually as seen above, which potentially doesn’t work since I’m seeing the default color curve value used at runtime.

1 Like