- Home /
The question is answered, right answer was accepted
Jump from position A to position B
I am making a simple 2D game and I have two platforms and you can jump left or right. I need the jump to be to a fixed position on the platform and I dont want it to just teleport there. Is there a way I can use lerp but with a jump (the curve jump makes)? Also I need the jump to be fast.
You could calculate parabola containing your A and B positions and animate the player along this parabola.
That's what i got for now. I will try to make working function. Are you able to unlock the question?
Answer by kubpica · Aug 18, 2018 at 10:40 PM
You could calculate parabola containing your A and B positions and animate the player along this parabola. Here is the simple version that takes the endpoint as an offset (only) in the X axis but it also allows you to specify height of the jump/parabola:
/// <summary>
/// Moves the object by a specified length along the parabola. (by kubpica)
/// </summary>
/// <param name="go"> The object to move.</param>
/// <param name="distance"> Distance by which to move the object. (Use negative values to move to the left.)</param>
/// <param name="height"> The height of the jump/parabola.</param>
/// <param name="time"> Animation time.</param>
/// <example>
/// Call the function this way:
/// <c>StartCoroutine (AnimateJump(gameObject, -2f, 1f, 1.0f));</c>
/// </example>
public static IEnumerator AnimateJump(GameObject go, float distance, float height, float time = 1.0f){ //parabola animation
Vector3 basePos = go.transform.position;
float x1 = 0;
float x2 = distance;
float x3 = (x1+x2)/2.0f;
float a = height/((x3-x1)*(x3-x2));
for (float passed = 0.0f; passed < time;) {
passed += Time.deltaTime;
float f = passed/time;
if(f>1) f=1;
float x = distance*f;
float y = a*(x-x1)*(x-x2);
go.transform.position = Change.X(go.transform.position, basePos.x+x);
go.transform.position = Change.Y(go.transform.position, basePos.y+y);
yield return 0;
}
}
Usage: StartCoroutine (AnimateJump(gameObject, -2f, 1f, 1.0f));
You need Change class for this code to work. You can get it here: http://answers.unity.com/comments/1543516/view.html
Update:
Here is the version that allows you to specify a particular endpoint and the parabola:
public static IEnumerator AnimateAlongParabola(GameObject go, Vector2 internalPoint, Vector2 endPoint, float time = 1.0f){
Vector3 basePos = go.transform.position;
float x1 = 0;
float y1 = 0;
float x2 = internalPoint.x;
float y2 = internalPoint.y;
float x3 = endPoint.x;
float y3 = endPoint.y;
float denom = (x1 - x2) * (x1 - x3) * (x2 - x3);
float A = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom;
float B = (x3*x3 * (y1 - y2) + x2*x2 * (y3 - y1) + x1*x1 * (y2 - y3)) / denom;
float C = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3) / denom;
float distance = x3-x1;
for (float passed = 0.0f; passed < time;) {
passed += Time.deltaTime;
float f = passed/time;
if(f>1) f=1;
float x = distance*f;
float y = A*x*x + B*x + C;
go.transform.position = Change.X(go.transform.position, basePos.x+x);
go.transform.position = Change.Y(go.transform.position, basePos.y+y);
yield return 0;
}
}
Calculations taken from https://stackoverflow.com/questions/717762/how-to-calculate-the-vertex-of-a-parabola-given-three-points
The code works but the ball keeps falling trough the platform. How do I fix that?
You can somehow break the animation when collision is detected or calculate another parabola formula that takes into account the specific end point, not just the horizontal distance . You got the idea.
Answer by ignacevau · Aug 18, 2018 at 08:44 PM
Supposing that you want to jump your player to 2 specific locations:
I would not try to actually jump my player to exactly these 2 locations. Although that this would be possible, it would take a lot of overcomplicated code to realize this.
One way to do it this way though would be to use the Lerp
method to move the player left/right and use AddForce()
to let the player move on the y-axis
(note that you would have to adjust your jump-height to land on the same time as your player arrives at the location on the x-axis)
I would not recommend to use
Lerp
here, instead useAddForce
using the Rigidbody2D component. You could add a seperate force for the y- and x-axis for easier adjustments. Then I would try to have it jump as good to the other platform as possible and if necessary adjust the position of one of the platforms.
In code this would look something like this:
Rigidbody2D rb;
public float JumpDistance;
public float JumpHeight;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
if(Input.GetKeyDown(KeyCode.RightArrow))
{
Jump(Vector2.right);
}
else if(Input.GetKeyDown(KeyCode.LeftArrow))
{
Jump(Vector2.left);
}
}
void Jump(Vector2 direction)
{
rb.AddForce(direction * JumpDistance);
rb.AddForce(Vector2.up * JumpHeight);
}
NOTE: Ofcourse you would have to make sure that the player is only able to jump again when it touches the ground and that the x-velocity is reset to 0.
Im not really looking for an add force alone code, because this jump is too slow. I need a fast jump, to literally transform object from one position to another but for it to look like a jump. Lerp works but it just teleports the player. I am trying to find a code that can combine lerp and jump so that the object is moved from position a to position b but it looks like jumping.
@sanja15513 You can always make the jump move faster by changing the Gravity Scale and increasing the jump height.
But I need a really smooth jump and for it to always land in the same position.