Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Spline linear distance calculation

Discussion in 'Scripting' started by Alturis2, Oct 8, 2023.

  1. Alturis2

    Alturis2

    Joined:
    Dec 4, 2013
    Posts:
    38
    I have been experimenting with the new Unity Splines package. And looking through SplineUtility there seem to be many functions that sound like what I want but they don't produce the result I would expect.

    What I am trying to do is take an object determined to be at a given distance along a spline's calculated distance.

    float splineDist = Spline.CalculateLength(transform.localToWorldMatrix);
    float objectDist = <value between 0 and splineDist>;
    float t = objectDist / splineDist;

    Vector3 point = Spline.EvaluatePosition( t );

    However, this produces a result where the objects will move faster near the spline start and end points and slower near the spline middle. Likely varies quite a bit depending on how the spline is defined.

    I have tried various flavors of ConvertIndexUnit, GetPointAtLinearDistance, GetNormalizedInterpolation etc but none of them are providing the result I am looking for. I want objects to move along the spline at a set speed, regardless of the curvature of the spline.
     
  2. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,001
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    This was one of the things I tried to give ChatGPT a few months back. It sort of got it right but then gave me some indexing defects... but it's a nonetheless interesting discussion of the problem space.

    https://chat.openai.com/share/6507f35b-c940-4406-8cd3-51a3ad92b6bf

    In any case, I haven't used the Unity package much but instead used this free Asset Store package:

    https://assetstore.unity.com/packages/tools/level-design/bezier-solution-113074

    It has a follow-by-speed function that should do what you need.
     
  4. Alturis2

    Alturis2

    Joined:
    Dec 4, 2013
    Posts:
    38
    Yeah I was hoping to not have to rely on SplineAnimate because I was experimenting in making things work more efficiently by doing all the deltas under the hood with simple float calculations and then translating the results to visuals only within the realm of what the player can see.

    Think Factorio or Satisfactory - wanting to manipulate things along conveyor belts that is going on all the time out of view, then translate that to the stuff going on around the player dynamically.

    I will look and see if SplineAnimate has any static utilities to do the same kind of calculations its doing. But was hoping there was a static utility or Spline method for this.
     
  5. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,001
    I wouldn't use built in Unity features if you want this much control and complexity.
     
  6. Alturis2

    Alturis2

    Joined:
    Dec 4, 2013
    Posts:
    38
    Well, that's not a great badge of quality for Unity. :)
    Splines package just feels like it needs a slight update here is all.
     
  7. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,001
    Your account is old, but I can't help but say: Welcome to Unity, where every feature is always just a slight update away from being usable.
     
    Kurt-Dekker likes this.
  8. Alturis2

    Alturis2

    Joined:
    Dec 4, 2013
    Posts:
    38
    In addition, I tried replacing the locomotion using SplineAnimate with speed set to 1 and the same issue occurs. So it seems that the spline system itself does not do this correctly.
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    Oh my goodness, I wish you were wrong.

    I love this engine so much but oh man it's so frustrating how they get to 99% and just... stop.

    Maddening.

    Caveat: I haven't used the specific spline package personally... I am just responding about all the other "not quite there" modules... and we've all wrestled with them from time to time.
     
    AcidArrow likes this.
  10. Alturis2

    Alturis2

    Joined:
    Dec 4, 2013
    Posts:
    38
    Another issue...


    float length = spline.Spline.GetLength();
    float distance = spline.Spline.CalculateLength(transform.localToWorldMatrix);

    length and distance appear to be completely different things and generate values way off.

    CalculateLength appears correct just by eyeballing its visual length in the editor, length I am not sure what GetLength is actually calculating. It appears to generate values much larger than the actual length of the spline.

    The problem being that I presume that things like GetPointAtLinearDistance() are based off the spline's GetLength() result but this does not appear to be the spline's actual length when extrapolated.

    e.g. one spline I have in my scene has a visual length of about 2.5 units. But the GetLength() is generating a value around 5.75
     
  11. Alturis2

    Alturis2

    Joined:
    Dec 4, 2013
    Posts:
    38
    Ok mystery solved. The real issue going on here was that I had my spline game object's transform scale set to 1, 0.05, 1 because I was trying to create a flat belt like tube out of the very limited SplineExtrude component which can only generate tubes. This was cause severe differences in the actual local space spline vs the world spline. So changing that to a thin rail instead resolved my issues.

    Lesson: If you use Unity Splines Package - keep your spline GameObject transform scale normalized. Or you will run into lots of headaches.

    However, this is revealing that the suite of SplineUtility functions needs a way to pass in the transform space you are talking about. You pass in a Spline but can only ever do so in local space. There is a major discrepancy there.
     
    Last edited: Oct 8, 2023
  12. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,001
    Skimming the docs it seems some parts of the API assume world space and others assume local space, which is... a choice.

    Being able to specify what space you want when using most of the API would be cool, but it would also be an unprecedented amount of robustness for the cross-off-the-checklist type feature that this spline package is.
     
  13. Alturis2

    Alturis2

    Joined:
    Dec 4, 2013
    Posts:
    38
    Well it seems like the most logical choice would be to provide a way for the spline to have knowledge of its transform. The SplineContainer is a component. It has spline(s) in it. Those splines should be able to derive their parent transform from that.

    but yes it does seem that the splines package from Unity was not designed to compete at all with existing third party packages. It’s almost as if it were designed as an example intended to be extended further.