Thank you for the answers.
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.
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?
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.
Any tricks to handle zero speed just like any non-zero speed?
Thanks in advance for any help on this.
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);
}
}
}