Announcement

Collapse
No announcement yet.

[SOLVED] SetLocationAtSplinePoint does not set the location

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [SOLVED] SetLocationAtSplinePoint does not set the location

    Hey guys.

    I'm using USplineComponent to give the player the ability to construct conveyor lines within a factory. The flow for constructing a conveyor line, goes something like this:
    1. The player picks the conveyor line type they wish to construct
    2. We spawn the actor with the USplineComponent and construct meshes along the spline based on various variables
    3. The actor follows the cursor around, by setting the actor location SetActorLocation()
    4. When the player clicks LMB, we will no longer move the entire actor, but move the last spline point (spline point index 0)
    5. When the player clicks LMB, nothing will follow the cursor anymore, and the player has now constructed a conveyor line.

    There is one step in the middle that I'd like the player to be able to do. That is raising and lowering the height of the conveyor, depending on what spline point we're currently moving around. If we're moving the entire actor, it's spline point at index 0. If the player already clicked the LMB once, and therefore we're only moving the last splint point index, it's spline point index 1.

    It should be said, that ew're talking about runtime functionality for the USplineComponent. This is not in the editor, but rather during gameplay.

    Consider the following function for raising (lowering is basically just the opposit on the Z axis)

    Code:
    void AConveyorLineNew::Raise()
    {
    int32 SplinePointToRaise = bInitialConstruct ? GetInitialConstructSplinePointToRaiseAndLower() : GetSplinePointToMove();
    FVector CurrentSplinePointLocation = Spline->GetLocationAtSplinePoint(SplinePointToRaise, ESplineCoordinateSpace::Local);
    
    // Create and add the elevation vector
    FVector ElevationVector(0.f, 0.f, ElevationAmountPerStep);
    FVector NewLocation = CurrentSplinePointLocation + ElevationVector;
    
    // If we've reached the maximum height limit
    if (NewLocation.Z > MaximumElevation)
    return;
    
    // Set the new location of the spline point that we're currently manipulating
    Spline->SetLocationAtSplinePoint(SplinePointToRaise, NewLocation, ESplineCoordinateSpace::Local);
    
    // Contruct meshes along the spline
    ConstructMeshes();
    }
    This all seems to work fine for spline point at index 0. Now, when the user clicks LMB once, we should raise/lower the second spline point, at index 1. This is where it goes wrong. I debugged, logged, and checked everything, but the location of the spline point at index 1, won't move at all, even though it should be raised 75 units on the Z axis.

    I get no errors what so ever, it's just as if the new location is not being set at the spline point index 1. If I hardcode to spline point index 0, both the raise as well as the lower function, works just fine. But it won't let me alter the Z axis value for spline point at index 1.

    Anyone know what's happening here?
    Last edited by Detilium; 05-23-2020, 05:02 AM.

    #2
    Code:
    void SetLocationAtSplinePoint
    (
    int32 PointIndex,
        const FVector & InLocation,
    ESplineCoordinateSpace::Type CoordinateSpace,
    bool bUpdateSpline
    )
    Maybe add true at the end of the function call?

    Comment


      #3
      Originally posted by ViperG View Post
      Code:
      void SetLocationAtSplinePoint
      (
      int32 PointIndex,
      const FVector & InLocation,
      ESplineCoordinateSpace::Type CoordinateSpace,
      bool bUpdateSpline
      )
      Maybe add true at the end of the function call?
      It's defaulting to true. Besides, this would also be a problem for the first splint point, at index 0, if that was the case
      Last edited by Detilium; 05-22-2020, 04:31 PM.

      Comment


        #4
        So index zero you can change but 1 you cannot? how about index 2 does that work?

        Comment


          #5
          Originally posted by ViperG View Post
          So index zero you can change but 1 you cannot? how about index 2 does that work?
          Correct. index 0 works fine, index 1 does not. I only have 2 spline points by design

          Comment


            #6
            Its possible its a bug, I found an older post using blueprints complaining about the same thing. I haven't used splines yet so I'm of no help. What happens if you try a different coordinate space does that do anything at all? (dont use local)

            [Edit]
            I found this:
            https://github.com/carla-simulator/c...utePlanner.cpp

            they are using world coordinate to move the spline points
            Last edited by ViperG; 05-22-2020, 04:51 PM.

            Comment


              #7
              Originally posted by ViperG View Post
              Its possible its a bug, I found an older post using blueprints complaining about the same thing. I haven't used splines yet so I'm of no help. What happens if you try a different coordinate space does that do anything at all? (dont use local)

              [Edit]
              I found this:
              https://github.com/carla-simulator/c...utePlanner.cpp

              they are using world coordinate to move the spline points
              Just tried it. Unfortunately no difference, but nice observation from your point

              Comment


                #8
                Ok looking at source code from the engine now...

                What value does this print out SplineCurves.Position.Points.Num() ?

                I ask because here is the code from the engine, maybe you're failing the check here:

                It might not count start and end as 2 spline points, it might only count everything passed the initial spline point. If that is the case, then you can never modify the last spline point, and if you need to do that, you would have to make the spline not not be last, but be 2nd to last, so you would have to add an extra spline point.

                Code:
                void USplineComponent::SetLocationAtSplinePoint(int32 PointIndex, const FVector& InLocation, ESplineCoordinateSpace::Type CoordinateSpace, bool bUpdateSpline)
                {
                const int32 NumPoints = SplineCurves.Position.Points.Num();
                
                if ((PointIndex >= 0) && (PointIndex < NumPoints))
                {
                const FVector TransformedLocation = (CoordinateSpace == ESplineCoordinateSpace::World) ?
                GetComponentTransform().InverseTransformPosition(InLocation) : InLocation;
                
                SplineCurves.Position.Points[PointIndex].OutVal = TransformedLocation;
                
                if (bUpdateSpline)
                {
                UpdateSpline();
                }
                }
                }
                Last edited by ViperG; 05-22-2020, 07:29 PM.

                Comment


                  #9
                  Found my issue.

                  The Raise and Lower methods modifies the Z value on the location. However, when the player is constructing a conveyor line, I'm altering the location of the conveyor line, each tick.
                  The following method was the one giving me issues:

                  Code:
                  void AConveyorLineNew::MoveToLocation(FVector Location)
                  {
                      if (bInitialConstruct)
                          SetActorLocation(Location);
                      else
                          Spline->SetLocationAtSplinePoint(GetSplinePointToMove(), Location, ESplineCoordinateSpace::World);
                  }
                  I need to first get the current location of the spline point, then set the Location.Z to the current Z value:

                  Code:
                  void AConveyorLineNew::MoveToLocation(FVector Location)
                  {
                      if (bInitialConstruct)
                          SetActorLocation(Location);
                      else
                      {
                          // To support raising and lowering the conveyor, we must get the current location to find the value on the Z axis.
                          FVector CurrentLocation = Spline->GetLocationAtSplinePoint(GetSplinePointToMove(), ESplineCoordinateSpace::World);
                          Location.Z = CurrentLocation.Z;
                  
                          Spline->SetLocationAtSplinePoint(GetSplinePointToMove(), Location, ESplineCoordinateSpace::World);
                      }
                  }
                  @ViperG: Thanks for the help. Really appreciate it!

                  Comment

                  Working...
                  X