0
\$\begingroup\$

My code can make a GameObject jump while simulating gravity. Now I want my GameObject to jump. The purpose of this is to always have a nice "touchdown".

Instead of the parabola, I want to use my jump script but I want it to jump using this relation with the other GameObject. I also need it to work while the target point is moving.

Could anyone solve this problem? An answer would be greatly appreciated. If you've got any questions, do not hesitate to reply (I understand that it's hard to understand...).

\$\endgroup\$
  • 6
    \$\begingroup\$ Wow - guys - don't downvote bountied questions to -1 on a whim, particularly when the OP is giving up all their points for the bounty - that's a real dick move. It may not be the best worded question in the world, but you could show the common decency to comment on it and suggest improvements rather than screwing the person over. Remember that once a bounty is committed to, it must be given, even if the answers are subpar. So show a bit of kindness to others. +1 just to cancel out that evil. \$\endgroup\$ – Engineer Nov 2 '15 at 17:55
  • 2
    \$\begingroup\$ @TheGameChanger I've edited your post to make it more readable - please let me know if this is now accurate - my understanding is you want to jump to some other point / GameObject but you want proper gravity as in your current code? If not, please explain and we can rollback the changes or edit accordingly. \$\endgroup\$ – Engineer Nov 2 '15 at 18:10
  • 4
    \$\begingroup\$ I'm confused by the recent edits to this question by The Game Changer. Earlier versions were clearly about jumping along an arc that would update mid-flight to land at a moving target position, but after accepting an answer about this topic you've made edits that have left the question extremely vague. "GameObject Issues" could describe half of all problems someone might have in an entity-based game engine, and the current question content doesn't define what you mean by "jump properly" or show us "my jump script." What is your intent with the recent edits? \$\endgroup\$ – DMGregory Nov 7 '15 at 1:45
  • 3
    \$\begingroup\$ I suggest this user be looked into and banned if necessary. I do not appreciate having the time I've taken to assist new users and carefully edit their questions, go down the drain. @TheGameChanger, if you wish to remain welcome on this site I suggest you cease and desist immediately. \$\endgroup\$ – Engineer Nov 12 '15 at 20:32
  • 1
    \$\begingroup\$ @John Indeed. I hope he finds what he wants, though... \$\endgroup\$ – Draco18s Dec 30 '15 at 18:45
8
+50
\$\begingroup\$

This ended up being simpler than I expected. Here is the process I followed so you can follow a similar process in the future:

I started writing the basic physics 101 equations with some values in 2d space because it's easier to think about:

a = (0, -9.8) // this is just gravity down
v = v0 + a*t  // velocity is starting velocity + acceleration times time
p = p0 + v0*t + (1/2)*a*t^2 // the position

and then, I assumed the target position would be relative to the start position, so p0 drops out. Rearraging to find v0, I got:

v0 = p - .5*a*t^2 / t

At this point, there are two things to solve for, v0, and t. This makes sense, you can throw a baseball right at your friend or way up high and still have it land at your friends location, even though it will take longer.

So, I took this and created the following two classes that have the desired effect.

public class Jumper : MonoBehaviour
{
    private Vector3 _velocity = Vector3.zero;
    public Vector3 _gravity = 9.8f * Vector3.down;

    public void Update()
    {
        _velocity += Time.deltaTime * _gravity;
        transform.position += Time.deltaTime * _velocity;
    }

    public void SetVelocityToJump(GameObject goToJumpTo, float timeToJump)
    {
        var toTarget = goToJumpTo.transform.position - this.transform.position;
        _velocity = (toTarget - (Mathf.Pow(timeToJump, 2) * 0.5f * _gravity)) / timeToJump;
    }
}

public class JumpTarget : MonoBehaviour
{
    public Jumper Jumper;
    public float TimeToJump;

    public void Start()
    {
        if (Jumper != null) Jumper.SetVelocityToJump(gameObject, TimeToJump);
    }
}

Edit to address comment If you want to keep the same position in the jump as the target moves, then you are no longer talking about a step-wise physics solution, at least not while the jump is happening. It is easily achieved, however, with a coroutine to handle the jump.

using UnityEngine;
using System.Collections;

public class Jumper : MonoBehaviour
{
    public Vector3 _gravity = 9.8f * Vector3.down;

    public void SetVelocityToJump(GameObject goToJumpTo, float timeToJump)
    {
        StartCoroutine(jumpAndFollow(goToJumpTo, timeToJump));
    }

    private IEnumerator jumpAndFollow(GameObject goToJumpTo, float timeToJump)
    {
        var startPosition = transform.position;
        var targetTransform = goToJumpTo.transform;
        var lastTargetPosition = targetTransform.position;
        var initialVelocity = getInitialVelocity(lastTargetPosition - startPosition, timeToJump);

        var progress = 0f;
        while (progress < timeToJump)
        {
            progress += Time.deltaTime;
            if (targetTransform.position != lastTargetPosition)
            {
                lastTargetPosition = targetTransform.position;
                initialVelocity = getInitialVelocity(lastTargetPosition - startPosition, timeToJump);
            }

            transform.position = startPosition + (progress * initialVelocity) + (0.5f * Mathf.Pow(progress, 2) * _gravity);
            yield return null;
        }
    }

    private Vector3 getInitialVelocity(Vector3 toTarget, float timeToJump)
    {
        return (toTarget - (0.5f * Mathf.Pow(timeToJump, 2) * _gravity)) / timeToJump;
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Where ever you are listening for the mouseup, when it is triggered, you need to call the SetVelocityToJump method on the Jumper with the desired parameters. \$\endgroup\$ – PatrickSharbaugh Nov 3 '15 at 16:20
  • \$\begingroup\$ I get an error when I run that. Can you suggest a correction? \$\endgroup\$ – That's me. Nov 3 '15 at 16:38
  • \$\begingroup\$ Take a look at my JumpTarget class above. The code that it executes on Start is what you need to do after detecting the mouse up. \$\endgroup\$ – PatrickSharbaugh Nov 3 '15 at 17:30
  • \$\begingroup\$ Thank you very much, my friend! You solved the problem! I've been struggling for a while now. \$\endgroup\$ – That's me. Nov 3 '15 at 17:46
  • \$\begingroup\$ If I have more questions related to your code, will you be able to respond? \$\endgroup\$ – That's me. Nov 3 '15 at 17:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.