Hello everyone,
I’ve been working with Unreal Engine blueprints but I’m new to learning C++ for game development. I have this weird behaving spline train track in unreal engine 4.27. I don’t know how to fix that, whether it is my mesh or my logic. I’d really appreciate some help.
(this is the mesh)
the video and image of track mesh are for reference and below is the implementation of the spline logic (I’ve made a custom C++ node and used it in construction script).
// Construction Script Logic (Called by Blueprint)
void ARailTrackSpline::ConstructRailTrack(float SegmentLength)
{
// 1 perform cleanup for old meshes
for (USplineMeshComponent* Mesh : RailSegments)
{
if (Mesh)
{
Mesh->DestroyComponent(); // Destroy the old components
}
}
RailSegments.Empty(); // Empty the array after destruction
// 2. Loop the meshes onto the spline points
const int32 NumSplinePoints = Rail_Track->GetNumberOfSplinePoints();
//safe check for not looping if the spline points are 0
// You need at least 2 points to form a segment.
if (NumSplinePoints < 2)
{
// Abort generation, but cleanup is already done.
UE_LOG(LogTemp, Warning, TEXT("Generation Aborted: Fewer than 2 spline points."));
return;
}
// divide total spline length into parts of Rail Track Length and then for each derivative spawn a track mesh
int32 TrackMeshesNeeded = (int32)(Rail_Track->GetSplineLength() / SegmentLength);
if (!(TrackMeshesNeeded > 0))
{
// Abort generation, but cleanup is already done.
UE_LOG(LogTemp, Warning, TEXT("Generation Aborted: Fewer than 1 Track Mesh Calculated"));
return;
}
const float OverlapCorrection = 1.0f; // Let's use 1.0 cm to test
// **We iterate through all segments. A spline with N points has N-1 segments.
for (int32 i = 0; i < /*NumSplinePoints*/ TrackMeshesNeeded - 1; ++i)
{
// 1. Get Geometry Data DIRECTLY at the Spline Points (no distance calculation needed!)
// Start Point Data (Point 'i')
FVector StartLocation, StartTangent;
//Rail_Track->GetLocationAndTangentAtSplinePoint(i, StartLocation, StartTangent, ESplineCoordinateSpace::Local); //get this data at spline point and set it
StartLocation = Rail_Track->GetLocationAtDistanceAlongSpline(i * SegmentLength, ESplineCoordinateSpace::Local);
StartTangent = Rail_Track->GetTangentAtDistanceAlongSpline(i * SegmentLength, ESplineCoordinateSpace::Local);
// End Point Data (Point 'i + 1')
FVector EndLocation, EndTangent;
//Rail_Track->GetLocationAndTangentAtSplinePoint(i + 1, EndLocation, EndTangent, ESplineCoordinateSpace::Local);
EndLocation = Rail_Track->GetLocationAtDistanceAlongSpline(((i + 1) * SegmentLength), ESplineCoordinateSpace::Local);
EndTangent = Rail_Track->GetTangentAtDistanceAlongSpline(((i + 1) * SegmentLength), ESplineCoordinateSpace::Local);
// 2. Create Mesh
USplineMeshComponent* SplineMesh = NewObject<USplineMeshComponent>(
this,
USplineMeshComponent::StaticClass(),
NAME_None,
RF_Transactional
);
if (SplineMesh)
{
// Set the mesh, register, and attach
SplineMesh->SetStaticMesh(RailSegmentMesh);
SplineMesh->RegisterComponent();
SplineMesh->AttachToComponent(Root, FAttachmentTransformRules::KeepRelativeTransform);
// Set the Start and End based on the data retrieved above
SplineMesh->SetStartAndEnd(
StartLocation, StartTangent,
EndLocation, EndTangent,
false
);
RailSegments.Add(SplineMesh);
}
}
}
