x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Procedural Spline-based Road Creation

So, I'm following along with this great tutorial:

Tutorial

The problem is that it seems to work when I do all the node hookups in the construction script. The SplineMesh is generated as expected more or less.

However, I'm building my road splines procedurally in c++ first. The splines are created, then the resulting spline is sent into a blueprint script to generate the splinemesh component. So, the SplineMeshes can't be created in the construction script. But when I run the code in that layout, the SplineMeshes do not appear to generate.

Is there any reason the SplineMeshComponent would misbehave in this way?

My Blueprint that calls the function that builds the SplineMesh : alt text

The spline that has been generated by code, but no accompanying SplineMeshes: alt text

The blueprint to create the SplineMesh based on the tutorial: alt text alt text

Product Version: UE 4.8
Tags:
more ▼

asked Jul 04 '15 at 10:17 AM in Blueprint Scripting

avatar image

Brandelan
210 12 17 24

avatar image Brandelan Jul 04 '15 at 09:09 PM

If anyone is interested, I just re-wrote some the basics of it in code, and it seems to work. Might have something to do with the RegisterAllComponents() call at the end, because if I leave that out, it doesn't build the static mesh, similar to how it wasn't building in BluePrint;

The InRoadSpline array at the beginning is just an array of vectors of each path that is built by my map generator, and the tileSize is the multiplier for the tiles of the map.

RoadDataArray is a struct that is mentioned in the video linked above to hold values for each tile's bank, thickness, and width;

If anything looks weird, or could be done better, feel free to give suggestions. I'm just learing c++ and culling together information from everywhere I can find it.

avatar image Brandelan Jul 04 '15 at 09:09 PM

EDIT: having trouble with board markup, never used this before

 void ARoadSpline::BuildRoadSpline(TArray InRoadSpline, int32 tileSize)
     {
         FVector tileMultiplier(tileSize, tileSize, 1);
     
         if (InRoadSpline.Num() >= 2)
         {
             //the first 2 points are created automatically, set them manually
             RoadSplineComp->SetWorldLocationAtSplinePoint(0, InRoadSpline[0] * tileMultiplier);
             RoadSplineComp->SetWorldLocationAtSplinePoint(1, InRoadSpline[1] * tileMultiplier);
     
             //set the remaining points if they exist
             for (int32 i = 2; i < InRoadSpline.Num(); i++)
             {
                 RoadSplineComp->AddSplineWorldPoint(InRoadSpline[i] * tileMultiplier);
             }
         }
     }
 
 
avatar image Brandelan Jul 04 '15 at 09:10 PM
 void ARoadSpline::BuildRoad()
     {
         //set the spline point counter to be equal to the number of spline points
         NumSplinePts = RoadSplineComp->GetNumSplinePoints();
     
         //make RoadDataArray the same length as the spline points
         if (RoadDataArray.Num() < NumSplinePts)
         {
             for (int32 i = 0; i < NumSplinePts; i++)
             {
                 RoadDataArray.Add(FRoadSplineData(0, 1, 1));
             }
         }
     
         else if (NumSplinePts < RoadDataArray.Num())
         {
             for (int32 i = RoadDataArray.Num(); i > NumSplinePts; i--)
             {
                 RoadDataArray.Remove(RoadDataArray.Last());
             }
         }
     
         BuildRoadMesh(RoadMesh);
     
     }
         

avatar image VICTRON_SL Jun 23 '17 at 03:57 AM

Hey there, I'm trying to achieve something like the ghost recon wildlands road system (which procedurally generates paths that become roads) and this is the closest result I have found... so if you could tell me if it is working properly and also you opinion about other ways that I searched to achieve this (because I'm new in programming) it would help me a lot, thanks

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first
  void ARoadSpline::BuildRoadMesh(UStaticMesh* inStaticMesh)
     {
         for (int32 i = 0; i < NumSplinePts - 1; i++)
         {
             /*
             *
             *initialize local variables
             *
             */
             int32 _currentLoopIndex(i);
             int32 _nextLoopIndex((i + 1));
     
             UStaticMesh* _StaticMesh = inStaticMesh;
     
             //set the Start location and tangent of the spline current location
             FVector _startLocation;
             FVector _startTangent;
             RoadSplineComp->GetLocalLocationAndTangentAtSplinePoint(_currentLoopIndex, _startLocation, _startTangent);
     
             //set the End location and tangent of the spline current location
             FVector _endLocation;
             FVector _endTangent;
             RoadSplineComp->GetLocalLocationAndTangentAtSplinePoint(_nextLoopIndex, _endLocation, _endTangent);
     
             //set the startRoll, and startScale
             float _startRoll(RoadDataArray[_currentLoopIndex].TrackBank);
             FVector2D _startScale(RoadDataArray[_currentLoopIndex].TrackWidth, RoadDataArray[_currentLoopIndex].TrackThickness);
     
             //set the startRoll, and startScale
             float _endRoll(RoadDataArray[_nextLoopIndex].TrackBank);
             FVector2D _endScale(RoadDataArray[_nextLoopIndex].TrackWidth, RoadDataArray[_nextLoopIndex].TrackThickness);
     
     
             /*
             *
             *start building the road
             *
             */
             USplineMeshComponent* _splineMesh = ConstructObject<USplineMeshComponent>(USplineMeshComponent::StaticClass(), this);
     
             _splineMesh->CreationMethod = EComponentCreationMethod::UserConstructionScript;
     
             _splineMesh->SetMobility(EComponentMobility::Movable);
             _splineMesh->AttachParent = RoadSplineComp;
     
             _splineMesh->SetStaticMesh(inStaticMesh);
     
             _splineMesh->SetStartScale(_startScale);
             _splineMesh->SetEndScale(_endScale);
     
             _splineMesh->SetStartRoll(_startRoll);
             _splineMesh->SetEndRoll(_endRoll);
     
             _splineMesh->SetStartAndEnd(_startLocation, _startTangent, _endLocation, _endTangent);
         }
     
         RegisterAllComponents();
     }

more ▼

answered Jul 04 '15 at 09:13 PM

avatar image

Brandelan
210 12 17 24

avatar image Doublezer0 Sep 30 '15 at 11:22 AM

ConstructObject is deprecated in 4.9 and the errors will tell you use to New Object instead. For Example :

USplineMeshComponent* SplineMesh = NewObject(this, USplineMeshComponent::StaticClass());

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question