How can I use DrawDebug functions in a Shipping build?

How can I use the DrawDebug functions like UKismetSystemLibrary::DrawDebugCircle() in a Shipping build? I don’t need them for actual debug purposes. I am using the DrawDebugCircle() as an indicator in the 3D world and have grown quite fond of it.

Is there some alternative method that we should be using?

I recreated DrawDebugCircle function that works in a shipping build using the UProceduralMeshComponent with a torus mesh. Actually, I ended up using the [URuntimeMeshComponent][1] since the UProceduralMeshComponent plugin blacklists the HTML5 platform because of collision generation. I didn’t need collision but I still couldn’t use UProceduralMeshComponent. Either class will work with the same algorithm.

void ABasePawn::CreateRuntimeMeshComponentTorus(URuntimeMeshComponent*& Torus, UMaterialInstanceDynamic* Torus_Mat, FLinearColor Color, int32 NumRadSegs, int32 NumTubeSegs, float TorusRad, float TubeRad)
{
	if (!Torus || !Torus_Mat)
	{
		UE_LOG(LogTemp, Error, TEXT("Torus or Torus_Mat is null"));
		return;
	}

	TArray<FVector> TorusPTs = TArray<FVector>();
	TArray<FVector> TorusNorms = TArray<FVector>();
	TArray<int32> TorusTris = TArray<int32>();

	for (int i = 0; i <= NumRadSegs - 1; i++)
	{
		for (int j = 0; j <= NumTubeSegs - 1; j++)
		{
			float AngleDegreesA = (360.f / NumRadSegs) * i;
			FVector A = FVector(1.f, 0, 0).RotateAngleAxis(AngleDegreesA, FVector(0, 0, 1.f));

			float AngleDegreesB = (360.f / NumTubeSegs) * j;
			FVector B = FVector(0, 0, 1.f).RotateAngleAxis(AngleDegreesB, FVector::CrossProduct(A, FVector(0, 0, 1.f)));

			FVector TorusPT = A * TorusRad + B * TubeRad;
			TorusPTs.Add(TorusPT);
			TorusNorms.Add(B);
		}
	}

	for (int i = 0; i <= TorusPTs.Num() - 1; i++)
	{
		int32 TubeSegsXRadSegs = NumTubeSegs * NumRadSegs;
		int32 Vert1 = (i + 1) % TubeSegsXRadSegs;
		int32 Vert2 = (i + NumTubeSegs + 1) % TubeSegsXRadSegs;
		int32 Vert3 = (i + NumTubeSegs) % TubeSegsXRadSegs;

		URuntimeMeshLibrary::ConvertQuadToTriangles(TorusTris, i, Vert1, Vert2, Vert3);
	}

	Torus->CreateMeshSection(0, TorusPTs, TorusTris, TorusNorms, TArray<FVector2D>(), TArray<FColor>(), TArray<FRuntimeMeshTangent>(), false, EUpdateFrequency::Average, ESectionUpdateFlags::None);

	Torus_Mat->SetVectorParameterValue(FName("BrushColor"), Color);
}

This function is adapted from this blueprint script: [TorusMaker][2]

Here’s the blueprint script from that post for convenience:

I applied a basic unlit material as a UMaterialInterface with:

Torus->CreateAndSetMaterialInstanceDynamicFromMaterial(0, Mat_Torus);

There is a simpler solution, you can call the Line functions directly from LineBatcher:

float LifeTime = 1.f;
bool bPersistentLines = false;
bool bDepthIsForeground = (0 == SDPG_Foreground);

ULineBatchComponent* LineBatcher = (InWorld ? (bDepthIsForeground ? InWorld->ForegroundLineBatcher : (( bPersistentLines || (LifeTime > 0.f) ) ? InWorld->PersistentLineBatcher : InWorld->LineBatcher)) : nullptr);

if (LineBatcher)
	LineBatcher->DrawLine(LineStart, LineEnd, FColor(1.f, 0.f, 0.f), 0, Thickness, LifeTime);
2 Likes