Why is my UNiagaraComponent null when using UNiagaraFunctionLibrary::SpawnSystemAttached

Hello community,

I’m trying to spawn projectiles that contain both Meshes and NiagaraSystems, I have a DataAsset that contains the relevant classes and properties for the spawning projectile which provides the variables via the parameter NewParams(using FProjectileParams struct).

When I spawn said projectile, the StaticMesh works fine, when I try to spawn the NiagaraSystem the function UNiagaraFunctionLibrary::SpawnSystemAttachedalways returns null and no effect appears.

Please see the code below:

void AProjectileBase::SetProjectileParams(const FProjectileParams& NewParams)
{
	if (IsValid(NewParams.ProjectileEffect))
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow,
		                                 FString::Printf(
			                                 TEXT("%s() Creating Niagara System, System='%s'"), *FString(__FUNCTION__),
			                                 *NewParams.ProjectileEffect->GetName()
			                                 ));
		
		// const UNiagaraComponent* NiagaraComp = UNiagaraFunctionLibrary::SpawnSystemAttached(
		// 	NewParams.ProjectileEffect,
		// 	MeshComponent,
		// 	NAME_None,
		// 	FVector(0.f),
		// 	FRotator(0.f),
		// 	EAttachLocation::Type::KeepRelativeOffset,
		// 	true);
		
		const UNiagaraComponent* NiagaraComp = UNiagaraFunctionLibrary::SpawnSystemAtLocation(
			GetWorld(),
			NewParams.ProjectileEffect,
			MeshComponent->GetComponentLocation(),
			MeshComponent->GetComponentRotation(),
			NewParams.Scale,
			false);
		
		// ParticleSystemComponent = NiagaraComp;

		if (IsValid(NiagaraComp))
		{
			// Set scale
			if (!NewParams.Scale.IsZero())
			{
				ParticleSystemComponent->SetRelativeScale3D(NewParams.Scale);
			}
		}
	}

	if (IsValid(MeshComponent) && IsValid(NewParams.ProjectileMesh))
	{
		MeshComponent->SetStaticMesh(NewParams.ProjectileMesh);
	}

	if (IsValid(ProjectileMovementComponent))
	{
		ProjectileMovementComponent->InitialSpeed = NewParams.Speed;
		ProjectileMovementComponent->MaxSpeed = NewParams.Speed;
		ProjectileMovementComponent->ProjectileGravityScale = NewParams.Gravity;
		ProjectileMovementComponent->bShouldBounce = NewParams.bShouldBounce;
		ProjectileMovementComponent->Bounciness = NewParams.Bounciness;
	}
}

From the commented-out section, you can see I’ve tried both SpawnSystemAttached and SpawnSystemAtLocation - neither return a resulting UNiagaraComponent and without the following IsValidthe engine crashes.

The DebugMessage does in fact show the System is correct and when I pause the debugger I can see all objects are not nullptrs.

This is for a multiplayer game using GAS to trigger the ability that spawns these projectiles.

Unreal Engine 5.5.4

// Header file for ProjectileBase
{
	GENERATED_BODY()

public:
	AProjectileBase();

	void SetProjectileParams(const FProjectileParams &NewParams);

protected:
	UPROPERTY()
	TObjectPtr<class UProjectileMovementComponent> ProjectileMovementComponent;
	UPROPERTY()
	TObjectPtr<class UNiagaraComponent> ParticleSystemComponent;
	UPROPERTY()
	TObjectPtr<class UStaticMeshComponent> MeshComponent;
};

// FProjectileParams struct
struct FProjectileParams
{
	GENERATED_BODY()

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	TSubclassOf<AProjectileBase> ProjectileClass;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	TObjectPtr<UStaticMesh> ProjectileMesh;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	TObjectPtr<UNiagaraSystem> ProjectileEffect;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	TObjectPtr<UShapeComponent> Collider;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	FVector Scale;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	float Speed = 1000.0f;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	float Gravity = .5f;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	float Range = 2000.0f;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	bool bShouldBounce = false;

	UPROPERTY(EditDefaultsOnly, Category = "Projectile")
	float Bounciness = 0.6f;
};

Any help would be greatly appreciated.

Thanks!

Double check your Niagara System asset is set up and passed correctly. Another possibility is it’s set up with culling that pre-culls the system.

Use your debugger to step INTO the SpawnSystemAttached down into the SpawnSystemAttachedWithParams and see exactly where it is bailing out and returning your null.

Thanks for the help - I can see that it fails the underlined if statement in the attached image but I’m not sure why, perhaps the dedicated server part? I’m new to UE and unsure on how best to spawn projectiles and effects, perhaps you can’t spawn Niagara Systems on the server?

That line checks whether you’re running ‘headless’ (with no graphics rhi pipeline) or running dedicated server… it won’t spawn those systems on a server, but it will if you’re hosting a multiplayer game you’re spawned into. Super strange place to fail if that’s not the case.

So I am spawning the projectile on the server and that spawn function tries to create the system - I assume that this isn’t going to work then as when I PIE, the editor is in listen server mode as I plan to have dedicated servers for this game.

Try using server RPC properly and check if the component is there already to hold your asset