Lightspeed
My contributions to Lightspeed

I implemented a procedural spline-based track generator in Unreal Engine 5 using C++.
The Class “ATrackGenerator” is as a Blueprint in the level and generates a full closed loop track when pressing the GenerateTrack button in the details panel.
This system supports:
-
Randomized track shape
-
SplineMesh track building
-
Start/Finish line position
-
Randomized obstacle spawning
— generate/Clear buttons
2 buttons in details panel

UFUNCTION(CallInEditor, Category="Track Generator")
void GenerateTrack();
UFUNCTION(CallInEditor, Category="Track Generator")
void ClearTrack();
— Procedural spline generation The track is generated by building spline points in local space, using a seeded
FRandomStream, then closing and updating the spline.
int32 UseSeed = bRandomizeEveryGenerate
? (int32)(FDateTime::UtcNow().GetTicks() & 0x7fffffff)
: Seed;
LastGeneratedSeed = UseSeed;
FRandomStream Stream(UseSeed);
Spline->ClearSplinePoints(false);
for (int32 i = 0; i < NumControlPoints; ++i)
{
const float T = (float)i / (float)NumControlPoints;
const float Theta = T * 2.f * PI;
float R = BaseRadius;
for (int32 k = 1; k <= Harmonics; ++k)
{
R += Amp[k] * FMath::Sin((k + 1) * Theta + Phase[k]);
}
FVector P(R * FMath::Cos(Theta), R * FMath::Sin(Theta), 0.f);
P.Z = BaseHeight + HeightVariation * FMath::Sin(HeightFreq * Theta + HeightPhase);
P = YawRot.RotateVector(P);
P += CenterOffset;
Spline->AddSplinePoint(P, ESplineCoordinateSpace::Local, false);
Spline->SetSplinePointType(i, ESplinePointType::Curve, false);
}
Spline->SetClosedLoop(true, false);
Spline->UpdateSpline();
— Track meshes using SplineMeshComponents Meshes are spawned along the spline using a calculated segment count and stable tangents.
const FVector StartDir = Spline->GetDirectionAtDistanceAlongSpline(StartDist, ESplineCoordinateSpace::Local);
const FVector EndDir = Spline->GetDirectionAtDistanceAlongSpline(EndDist, ESplineCoordinateSpace::Local);
const FVector StartTan = StartDir * TangentLen;
const FVector EndTan = EndDir * TangentLen;
SplineMesh->SetStartAndEnd(StartPos, StartTan, EndPos, EndTan, true);
SplineMesh->SetSplineUpDir(FVector::UpVector, false);
SplineMesh->bSmoothInterpRollScale = true;
— Auto segment sizing + safety cap The generator can compute effective segment length from the mesh bounds (including a forward-scale multiplier) and clamp the segment count.
float MeshLen = 2.f * Extent.X;
float ForwardScale = TrackPieceScale.X;
EffectiveSegmentLength = FMath::Max(50.f, (MeshLen * ForwardScale) * MeshLengthMultiplier);
const int32 DesiredSegments = FMath::CeilToInt(SplineLen / EffectiveSegmentLength);
const int32 NumSegments = FMath::Clamp(DesiredSegments, 1, MaxMeshSegments);
— Start/Finish line as a spawned Actor The start/finish line is spawned from an assignable StartFinishClass and placed at spline distance 0 with offsets.

FTransform T = Spline->GetTransformAtDistanceAlongSpline(0.f, ESplineCoordinateSpace::World, true);
FRotator R = T.GetRotation().Rotator();
R.Yaw += StartFinishYawOffset;
T.SetRotation(R.Quaternion());
T.AddToTranslation(T.GetRotation().RotateVector(StartFinishLocalOffset));
SpawnedStartFinishActor = World->SpawnActor<AActor>(StartFinishClass, T, Params);
— Random obstacle spawning Obstacles spawn as BP actors along the spline with spacing and scaling controls.

float D = Stream.FRandRange(StartSafeDistance, Len - StartSafeDistance);
FTransform T = GetTransformAtDistance(D, Lateral, ObstacleVerticalOffset);
AActor* Obstacle = World->SpawnActor<AActor>(ObstacleClass, T, Params);
Obstacle->SetActorScale3D(FVector(
Stream.FRandRange(ObstacleScaleMin.X, ObstacleScaleMax.X),
Stream.FRandRange(ObstacleScaleMin.Y, ObstacleScaleMax.Y),
Stream.FRandRange(ObstacleScaleMin.Z, ObstacleScaleMax.Z)
));
ATrackGenerator is an editor-driven tool, it generates a randomized closed loop spline track, builds stable spline meshes with performance safeguards, supports scalable segments, spawns a start/finish actor for collision/logic, and can spawn scalable randomized obstacle actors along the track.
-Jamie
Here are some Lightshot Images!



