Hi,
I’m looking for a method to approximate the speed/distance curve of a sprinter from start to finish.
For sprinting, the applied force differs over time until max speed is reached.
My use case is that I want a character to move as fast it can to a target position. If the position is relatively close, max speed won’t be reached and the character will stop at the desired position. If the position is far away max speed will be reached. In both cases, I want deceleration to be abrupt as believably possible.
My plan is to plug a speed value into an animation controller with a movement blend tree based on speed.
As I understand it, I need to set the velocity each frame. Maybe, I’m over thinking this, but one thought I had was that I could create a table (array) of max speed percentages (based on the graph above) over time.
Deceleration will begin once the min required stopping distance is reached. So far I haven’t found any data on how much distance a sprinter at max speed needs to stop, but I’m ok using an approximation.
The reason for abrupt deceleration is that my game is grid based, which requires sharp 45 and 90 degree turns.
ok thanks. I’ve educated myself a bit on animation curves and I think it’s going work out very well to control the velocity over time.
I just have one further question.
What is the best way to extract the velocity from the root motion of an animation clip? I want to use this value for blend tree thresholds (from walk to sprint)? The reason I’m asking is that my characters are rigid bodies and I’m not using root motion to move them.
Thanks for the help, but I managed to figure it out. All I had to do was compute thresholds for Velocity Z and it automatically pulled in the average speed of each animation.
I now have a perfectly animating character that moves smoothly using rigidbody motion only.
Here is a snip of the code for anyone who is interested.
public AnimationCurve velocityCurve;
private float currentVelocity = 0.0f; //this is our current velocity
private float moveDuration = 0f; // time since moving forward started
private const float maxMoveSpeed = 6f;
private const float maxTime = 6.0f; // the time in seconds at which max speed is reached.
/// <summary>
/// Sets the velocity, should be called in FixedUpdate()
/// </summary>
private void SetVelocity()
{
if (isMoving)
{
moveDuration += Time.deltaTime;
currentVelocity = velocityCurve.Evaluate(moveDuration / maxTime) * maxMoveSpeed;
currentVelocity *= figure.transform.localScale.y; // modify velocity by the height of figure
}
else
{
moveDuration = 0;
currentVelocity = 0;
}
}
/// <summary>
/// Moves the figure forward by the current Velocity. Should be called on FixedUpdate()
/// </summary>
public void MoveForward()
{
isMoving = true;
rigidBody.isKinematic = false;
Vector3 pos = figure.transform.position + (figure.transform.forward * currentVelocity * Time.deltaTime);
rigidBody.MovePosition(pos);
}