Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Parallel Splines
#1
Hey there,

I made this mesh by generator.
https://gyazo.com/2a9e635a257d5cf43bb4b850f7b1007e

As you see there are four lanes. I want to know how it is possible to have parallel paths for moving objects on them ?
I tried to duplicate the path which mesh is created with and put them besides each other with some offset but some parts are not parallel.
https://gyazo.com/64107c92565077ee5c50dd50d4717fd7
Reply
#2
I think I found the solution.

I use this piece of code for offsetting between characters.

Code:
[Section("Lane", Sort = 0)]
[SerializeField] private float _offset = 5f;

/// <summary>
/// This is called just after the SplineController has been initialized
/// </summary>
protected override void UserAfterInit()
{
   SetOffset();
}

/// <summary>
/// This is called just after the SplineController updates
/// </summary>
protected override void UserAfterUpdate()
{
   SetOffset();
}

void SetOffset()
{
   if (Spline.Dirty)
       Spline.Refresh();

   transform.Translate(_offset, 0, 0, Space.Self);
}


Is it correct ? Or there is a better way to do so ? Any way to consider separate path for each lane ?
Or is it possible to generate meshes a curvy spline path and then generate separate splines for 4 lanes ?

Look at this image:
https://gyazo.com/206d782ecc94c9d68ef3bf929bac66d9
As you see 4 parallel lanes are changed to 2 pairs. I want 2 separate splines for right one and 2 for left one and connection between 4 lanes to 2 pairs of 2 lanes. You know what I mean ?

[Edit]

I wrote these codes for lane changing and spline switching at connection. Do you think it is a good approach or there is a better one ?

This one attached to the character:

Code:
public class CharacterController : SplineController
{
   [Section("Lane", Sort = 0)]
   [SerializeField] private float _offset = 5f;
   [SerializeField] private float _changeingLaneTime = 0.5f;

   private float _targetOffset;
   private IEnumerator _lerpOffset;
   private int _minOffset;
   private int _maxOffset;

   /// <summary>
   /// This is called just after the SplineController has been initialized
   /// </summary>
   protected override void UserAfterInit()
   {
       _targetOffset = _offset;
       _minOffset = -3;
       _maxOffset = 3;

       SetOffset();
   }

   /// <summary>
   /// This is called just after the SplineController updates
   /// </summary>
   protected override void UserAfterUpdate()
   {
       ChangeLane();
       SetOffset();
   }

   void SetOffset()
   {
       if (Spline.Dirty)
           Spline.Refresh();

       transform.Translate(_offset, 0, 0, Space.Self);
   }

   private void ChangeLane()
   {
       if (Input.GetKeyDown(KeyCode.RightArrow))
       {
           _targetOffset = Mathf.Clamp(_targetOffset + 2, _minOffset, _maxOffset);
           StartLerpingOffset(_targetOffset);
       }

       if (Input.GetKeyDown(KeyCode.LeftArrow))
       {
           _targetOffset = Mathf.Clamp(_targetOffset - 2, _minOffset, _maxOffset);
           StartLerpingOffset(_targetOffset);
       }
   }

   private void StartLerpingOffset(float amount)
   {
       if (_lerpOffset != null)
       {
           StopCoroutine(_lerpOffset);
       }
       _lerpOffset = LerpOffset(_offset, amount);
       StartCoroutine(_lerpOffset);
   }

   IEnumerator LerpOffset(float current, float target)
   {
       float currentTime = 0;
       float perc = 0;

       while (perc != 1)
       {
           currentTime += Time.deltaTime;
           if (currentTime > _changeingLaneTime)
           {
               currentTime = _changeingLaneTime;
           }
           perc = currentTime / _changeingLaneTime;
           _offset = Mathf.Lerp(current, target, perc);
           yield return null;
       }
   }

   private void ChangeOffsetLimit(int[] offsets)
   {
       _minOffset = Mathf.Min(offsets);
       _maxOffset = Mathf.Max(offsets);
   }

   private void ControlTracks(CurvySplineMoveEventArgs e)
   {
       ControlPointMetaData cpMetaData = e.ControlPoint.GetComponent<ControlPointMetaData>();

       if (cpMetaData != null && Array.Exists(cpMetaData.supportingOffsets, _ => _ == _targetOffset))
       {
           ChangeOffsetLimit(cpMetaData.supportingOffsets);
           return;
       }

       if (e.ControlPoint.Connection == null)
       {
           return;
       }

       for (int i = 0; i < e.ControlPoint.Connection.ControlPointsList.Count; i++)
       {
           CurvySplineSegment currentControlPoint = e.ControlPoint.Connection.ControlPointsList[i];
           ControlPointMetaData currenCPMetaData = currentControlPoint.GetComponent<ControlPointMetaData>();
           if (currenCPMetaData != null && Array.Exists(currenCPMetaData.supportingOffsets, _ => _ == _targetOffset))
           {
               Vector3 lookupPos = Spline.transform.InverseTransformPoint(transform.position);
               float nearestPointTF = currentControlPoint.Spline.GetNearestPointTF(lookupPos);
               Spline = currentControlPoint.Spline;
               Position = nearestPointTF;
               ChangeOffsetLimit(currenCPMetaData.supportingOffsets);
               break;
           }
       }
   }

   public void OnCPReached(CurvySplineMoveEventArgs e)
   {
       ControlTracks(e);
   }
}

This one attached to the control points which has connections:
Code:
public class ControlPointMetaData : MonoBehaviour
{
   public int[] supportingOffsets;
}
Reply
#3
Hi,
I will answer first about having multiple lanes:
  • Your solution (the offset) is good in mhy opinion as long as it gives you the desired result
  • A solution similar to yours would have been to use the already existing Offset feature instead of coding yours
  • Before explaining the next solution, you should make the distinction between the usage of the words Spline and Path in the context of Curvy: A spline is what contains the control points. Once the spline is rasterized to be used in a Curvy Generator, it becomes a path. This process happens in the Input Spline Path module
    So, based on this, my first to go solution would have been to use the Path Relative Translation module to translate paths, and use a Path Controller instead of a Spline Controller to move your objects
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply
#4
Now about switching between lanes:
  • First of all, know that there is a SwitchTo method in spline controller that does (from my understanding) the same thing that your code, with the exception that it need two different splines to switch between.
  • I think what i would have done, is to consider each road as a different spline, and lanes inside each road as different offsets, then use the SwitchTo and Offset features of the Spline Controller to navigate between different roads/lanes
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply
#5
(01-28-2020, 09:44 AM)_Aka_ Wrote: Hi,
I will answer first about having multiple lanes:
  • Your solution (the offset) is good in mhy opinion as long as it gives you the desired result
  • A solution similar to yours would have been to use the already existing Offset feature instead of coding yours
  • Before explaining the next solution, you should make the distinction between the usage of the words Spline and Path in the context of Curvy: A spline is what contains the control points. Once the spline is rasterized to be used in a Curvy Generator, it becomes a path. This process happens in the Input Spline Path module
    So, based on this, my first to go solution would have been to use the Path Relative Translation module to translate paths, and use a Path Controller instead of a Spline Controller to move your objects

About Offset feature how can it be same as mine ? Because I try to use it but no success. It is good on Y axis but by changing Offset Angle I don't find good angle for changing in X axis.

I didn't understand why I should use Path Relative Translation ? As I see it just translate the mesh.

(01-28-2020, 09:54 AM)_Aka_ Wrote: Now about switching between lanes:
  • First of all, know that there is a SwitchTo method in spline controller that does (from my understanding) the same thing that your code, with the exception that it need two different splines to switch between.
  • I think what i would have done, is to consider each road as a different spline, and lanes inside each road as different offsets, then use the SwitchTo and Offset features of the Spline Controller to navigate between different roads/lanes

I think I did the same thing. There are 2 roads, one is a main one another is the one at the right side of the main one which has 2 connection with the main one. Then at the connection points I check that ControlPointMetaData to see what offsets are supported by that control point and according to the current player offset I change spline. (I tried to use SwtichTo but it was confusing for me so I decided to change the spline directly). Do you think it is same as you ?
Reply
#6
(01-28-2020, 10:43 AM)ATHellboy Wrote: About Offset feature how can it be same as mine ? Because I try to use it but no success. It is good on Y axis but by changing Offset Angle I don't find good angle for changing in X axis.
You are right, there are not the same. Yours translates in an axis relative to the moved object, mine translates in an axis relative to the spline.

(01-28-2020, 10:43 AM)ATHellboy Wrote: I didn't understand why I should use Path Relative Translation ? As I see it just translate the mesh.
You can use it to have a translated path not to be used for the mesh extrusion, but as an input to a Path Controller

(01-28-2020, 10:43 AM)ATHellboy Wrote: I think I did the same thing. There are 2 roads, one is a main one another is the one at the right side of the main one which has 2 connection with the main one. Then at the connection points I check that ControlPointMetaData to see what offsets are supported by that control point and according to the current player offset I change spline. (I tried to use SwtichTo but it was confusing for me so I decided to change the spline directly). Do you think it is same as you ?
It's not the same, but yours answers more directly your needs, so I think you should stick with it. Curvy comes with a lot of pre-made solutions, but it is always best that users make their own specific solutions using the API.
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply


Possibly Related Threads...
Thread Author Replies Views Last Post
  Best practice for multiple splines digot 2 62 02-18-2020, 03:37 PM
Last Post: digot
  Bending meshes along splines digot 2 167 01-30-2020, 02:15 PM
Last Post: digot
Big Grin How to get a point in Spline that is parallel with another Spline? curvyuser007 5 284 01-20-2020, 10:18 PM
Last Post: curvyuser007
  Import splines from GeoJson Qpid36 4 543 11-22-2019, 03:45 PM
Last Post: _Aka_

Forum Jump: