Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Setting speed manually
#1
This Curvy thing is awesome. After following the tutorial, I have an object following a spline. However, I'm trying to get full manual control over the speed of the object. I need to use an externally generated value to move the object a a rate represented by that number (for example: 50 mph). The speed value will change from zero to some real vehicle speed maximum (like 150 mph or so) So, for example, the game begins, the externally generated number changes from zero to some positive non-zero value and the object following the spline path needs to track in the spline at whatever speed that value is, updated continuously. I already have the externally generated value for speed in code. It can't have any other influence over the speed. Simply jump instantaneously to the external number supplied for the speed. Trying to connect the variable up to the spline controller but I can't see how to do it. Maybe the solution is right in front of me and I'm just not seeing it? Anyone?


Thanks
Reply
#2
Sounds like you should most likely just create your own Controller:
- it can be based on the existing SplineController
- or if you want to use physics and move your target object by forces, you could also do something like "RigidBodySplineController.cs" (which you can find under Assets\Packages\Curvy Examples\Scripts\RigidBodySplineController.cs).

You can then control the "speed" anyway you want.

Basically, if you understand how some important methods work you can just create a Controller of your own easily.
I'll give you an example here:

Code:
public int speed = 10;
public CurvySpline spline;

private float TFv = 0f; // this represents where you are on the spline (range 0..1)

void Update()
{
 if(TFv < 1f)
 {
   TFv += speed * Time.deltaTime; // go further on the spline using the "speed"
   Vector3 worldPoint = spline.InterpolateFast(TFv); // get the actual world point from the spline that corresponds to the total fragment value (TFv)
   Vector3 fwd = spline.GetTangentFast(TFv); // you get the orientation so you can maybe set the transform.forward you want to "fwd"

   transform.position = worldPoint;
   transform.forward = fwd;
 }
}

This is not tested, just an "idea".
Hope it helps.
Reply
#3
No need to write a controller from scratch (though that works of course). Just inherit from SplineController and change the Speed property in UserAfterUpdate(). See here for an example.
Reply
#4
Smile 
Thank you for the answers. Big Grin

I've finally gotten around to working on this again.

I started with the example 01_MetaData.unity and modified the MetaDataController.cs script to change the Speed property in the routine UserAfterUpdate() as stated. I added a slider to the Canvas to control the speed (its OnValueChanged calling MetaDataController.MySpeed in the code below).

It works to a point. Speed goes up when the slider value increases. Speed goes down when the slider value goes down.

When the 'Speed' property reaches zero, the spaceship object stops. So far, good.

But, when the Speed property is once again set positive from zero, the spaceship continues to stand still. It seems that once the Speed property is set to zero, it no longer works.   Huh

Looking into it some more it seems that Speed is set to zero, the method UserAfterUpdate() stops being called.
Looked at CurvyController.cs and found that calling this.Refresh() should kick it back in.

So to patch it I've placed a this.Refresh() in the setter for MySpeed as shown here:

Code:
        public float MySpeed
        {
            get { return m_MySpeed; }
            set
            {
                if (m_MySpeed != value)
                {
                    m_MySpeed = value;
                    Debug.Log("MySpeed Changed To: " + m_MySpeed);
                    this.Refresh();
                }
            }
        }


Is it by design that UserAfterUpdate() is stopped at zero speed? (I didn't find in the code where this is actually happening).

Is the solution shown below a proper way to modify the Speed or am I all messed up? Blush


I'd prefer that everything keep processing (UserAfterUpdate()) and not have to do a refresh to kick it back on if that's doable. Sure I can set a switch when speed reaches zero and just check the switch and speed combined to only call refresh when necessary but that seems like a bit of fooling around when I'm probably just missing something again. Undecided

Any tricks to handle zero speed just like any non-zero speed?

Thanks in advance for any help on this. Smile


Code:
namespace FluffyUnderware.Curvy.Examples
{

   /// <summary>
   /// Example custom Controller
   /// </summary>
   public class MetaDataController : SplineController
   {
       //The section attribute renders our field inside it's own category!
       [Section("MetaController",Sort=0)]
       [RangeEx(0, 30)]
       [SerializeField]
       float m_MaxHeight = 5f; // The height over ground to use as default

       [Section("MetaController")]
       [RangeEx(0, 100)]
       [SerializeField]
       float m_MySpeed = 0f;

       public float MaxHeight
       {
           get { return m_MaxHeight; }
           set
           {
               if (m_MaxHeight != value)
                   m_MaxHeight = value;
           }
       }

       public float MySpeed
       {
           get { return m_MySpeed; }
           set
           {
               if (m_MySpeed != value)
               {
                   m_MySpeed = value;
                   Debug.Log("MySpeed Changed To: " + value);
                   this.Refresh();               }
           }
       }

       /// <summary>
       /// This is called just after the SplineController has been initialized
       /// </summary>
       protected override void UserAfterInit()
       {
           setHeight();
       }
       /// <summary>
       /// This is called just after the SplineController updates
       /// </summary>
       protected override void UserAfterUpdate()
       {
           setHeight();
           this.Speed = m_MySpeed;
       }


       void setHeight()
       {
           // Get the interpolated Metadata value for the current position (for SplineController, RelativePosition means TF)
           // If values can't be interpolated (no next value), current value (if present) or default type value (for float that's 0) is returned
           var v = Spline.InterpolateMetadata<HeightMetadata,float>(RelativePosition);
       
           // In our case we store a percentage (0..1) in our custom MetaData class, so we multiply with MaxHeight to set the actual height.
           // Note that position and rotation  has been set by the SplineController previously, so we just translate here using the local y-axis
         
           transform.Translate(0, v * MaxHeight, 0, Space.Self);
         
       }

       public void ShowSettings()
       {
           Debug.Log("this.Speed: " + this.Speed);

           Debug.Log("IsInitialized: " + this.IsInitialized);
           Debug.Log("IsConfigured: " + this.IsConfigured);
           Debug.Log("IsPlaying: " + this.IsPlaying);
           Debug.Log("isActiveAndEnabled: " + this.isActiveAndEnabled);
           Debug.Log("Active: " + this.Active);
           Debug.Log("IsSwitching: " + this.IsSwitching);
           Debug.Log("PositionMode: " + this.PositionMode);
           Debug.Log("Direction: " + this.Direction);
       }


   }
}
Reply
#5
Good point and not working like intended. Please edit CurvyController.cs, locate the Speed property and add mForceUpdate to the setter:

Code:
public float Speed
        {
            set
            {
                //...
                mForceUpdate = true;
            }
        }

That should do the trick! I'll test this and add the fix to 2.0.5...
Reply
#6
That did the trick..... Works as I'd expect now.

Thank you very much   Smile
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Controler Speed from metadata Bryan Thatcher 4 10 06-25-2024, 11:18 AM
Last Post: _Aka_
  How could I manually set the bound? Chanon 1 8 09-17-2023, 10:11 AM
Last Post: _Aka_
Question Setting instantiated object to spline, then starting movement? _RicO 3 9 06-28-2023, 06:01 PM
Last Post: _Aka_
  Manually controlling scale of each CP Maldruzard 1 5 03-27-2023, 10:58 AM
Last Post: _Aka_

Forum Jump: