Download

Collision for SplineMeshComponents

Hey guys.

I’m using splines at runtime, to let the player construct conveyor belt lines. Each conveyor belt line, consists of several conveyor belts. The conveyor belts are evenly distributed along the spline, by calculating the total number of spline mesh components, depending on the spline length and the width of the conveyor belt static meshes.

Description
To construct a conveyor belt line, the player must select the conveyor belt from a certain menu. The conveyor belt actor will then follow the mouse around, until the player click and hold the left mouse button. This will lock the first spline point, and move the second spline point to follow the cursor. Whenever the player let go of the left mouse button, the conveyor line will be constructed (the last spline point will no longer follow the mouse). This is where I encounter my issue with the spline mesh component collision.

Issue
If any of the spline mesh components are overlapping with any object that matches the collision settings, the conveyor belt line should NOT be constructed. The following code is how I thought I could accomplish this task:


// ConveyorBeltLine.cpp

void AConveyorLine::BuildSplineMesh(int32 Distance, int32 DistanceAlongSpline)
{
    auto NewMesh = NewObject<USplineComponent>(this);
    NewMesh->CreationMethod = EComponentCreationMethod::Instance;
    NewMesh->SetMobility(EComponentMobility::Movable);
    NewMesh->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRealtiveTransform);
    NewMesh->ResetRelativeTransform();

    AssignStaticMeshToSplineMeshComponent(Distance, NewMesh);
}

void AConveyorLine::AssignStaticMeshToSplineMeshComponent(int32 Distance, USplineMeshComponent* SplineMesh)
{
    auto Location = Spline->GetLocationAtDistanceAlongSpline(Distance, ESplineCoordinateSpace::Local);
    SplineMesh->SetStaticMesh(ConveyorBeltMesh);
    SplineMesh->SetRelativeLocation(Location);
    SplineMEsh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
    SplineMesh->UpdateMesh();
}

// This method is called whenever the left mouse button has been let go
bool AConveyorLine::CanBuildHere()
{
    TArray<AActor*> OverlappingActors();
    GetOverlappingActors(OverlappingActors);

    return OverlappingActors.Num() == 0;
}

Notice the last method AConveyorLine::CanBuildHere(). I would suppose that GetOverlappingActors() for the entire actor, would check collision for every component attached to it, but OverlappingActors.Num() is equal to 0, even though the conveyor line is overlapping other actors. I checked the collision settings, and they look exactly as I expect.

As you can see in the image above, Generate Overlap Events is turned on, the object type is ConveyorBelt, and is blocks other ConveyorBelt objects. However, at runtime, though having the CanBuildHere method, I can still do this:
Visualization-of-problem.JPG

'This should not be able to happen, as some of the spline mesh components are overlapping with other spline mesh components.

I’m not quite sure why this isn’t working, so I’m hoping for some kind of guidance in here :slight_smile:

Have you tried calling “UpdateOverlaps” first? Pretty sure GetOverlappingActors just returns the most recent list of overlaps, it doesn’t actually perform the overlaps query (UpdateOverlaps, or moving the component), does that.

Doesn’t seem to make any difference. I did however, try to view the collision at runtime (the “Show” button in the viewport), and it does look like there is valid collision boxes.