0

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...).

That's me.
  • 349
  • 3
  • 10
  • 24
  • I'd suggest taking a look at the graph of an object effected by physics. The shape is in fact a parabola reguardles of the starting y location, ending y location, starting x location, and ending x location. That said, when the object moves further ahead, you adjust the x,y velocity accordingly. Though this wouldn't be a proper solution as your Z is basically determined and set at jump... – moonshineTheleocat Nov 02 '15 at 16:57
  • 6
    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. – Engineer Nov 02 '15 at 17:55
  • 2
    @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. – Engineer Nov 02 '15 at 18:10
  • Corrected. Hope you get the answer you need! – Engineer Nov 03 '15 at 08:57
  • 4
    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? – DMGregory Nov 07 '15 at 01:45
  • 3
    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. – Engineer Nov 12 '15 at 20:32
  • Based on the comment in the bounty that was added 5 minutes ago, I feel that it should have been a new question, as it seems to be asking, "I want it to jump to point A, then jump to point B, then point C, etc." and asking how to make the jumps occur automatically, e.g. as if the character lands on a series of jump-boost-pads / trampolines. – Draco18s no longer trusts SE Dec 30 '15 at 18:13
  • @Draco18s I don't want to ask a new question because I want the answer to be based off PatrickSharbaugh's second code (his "Edit to address comment"). –  Dec 30 '15 at 18:37
  • @John you can reference prior questions in new ones with links easily enough. Editing the question such that the question itself has mutated to something that the original answers no longer address is frowned upon at best. The grammar of the (new? current?) question is also horribly unreadable and lacks any kind of explanatory images that the original question had, that I have no idea what the asker wants. – Draco18s no longer trusts SE Dec 30 '15 at 18:41
  • @Draco18s Well, I guess it's too late now... ;) The bounty has already been started. –  Dec 30 '15 at 18:44
  • 1
    @John Indeed. I hope he finds what he wants, though... – Draco18s no longer trusts SE Dec 30 '15 at 18:45
  • #ArcaneEngineer Bounty doesn't make a bad question a good question. So many details are missing. Is it 3D? Are the jumps controlled by the player? What is a nice touchdown? And what is the cycle that continues? Is the jumping repeating? Are the target GameObjects platforms or positions? – JPtheK9 Dec 31 '15 at 17:16
  • @JPtheK9 Just forget about the bad question. In order to receive +100, you have to read what I said in the bounty box. It seems like user who asked the question is now suspended and cannot edit the question. I kindly ask the moderators to rollback the question to a better version. –  Dec 31 '15 at 17:22
  • 1
    This person wants @PatrickSharbaugh to provide him with more free code. This person is using Stack Exchange as a means for free labour. This is not what this site is about. – jgallant Jan 04 '16 at 12:57

1 Answers1

8

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;
    }
}
  • 1
    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. – PatrickSharbaugh Nov 03 '15 at 16:20
  • I get an error when I run that. Can you suggest a correction? – That's me. Nov 03 '15 at 16:38
  • 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. – PatrickSharbaugh Nov 03 '15 at 17:30
  • Thank you very much, my friend! You solved the problem! I've been struggling for a while now. – That's me. Nov 03 '15 at 17:46
  • If I have more questions related to your code, will you be able to respond? – That's me. Nov 03 '15 at 17:48
  • Just post them on the site here as new questions. – PatrickSharbaugh Nov 03 '15 at 17:49
  • A quick fix could be adding a child game object to the target object and positioning it at it's edge, then passing that child object to the jumper. – PatrickSharbaugh Nov 03 '15 at 19:01
  • You'll probably get somewhat more accurate results if you use transform.position += Time.deltaTime * (_velocity - 0.5 * Time.deltaTime * _gravity); in your Update() method, so as to match the "physics 101" formula also within each time step. See here for more details. Of course, with a small enough deltaTime, the error may be negligible. – Ilmari Karonen Nov 11 '15 at 22:07
  • There's a small issue. The jump time (from initial position to target) is a bit different every time the target is at a different position. For example, the first elapsed time was 4.158663 and the second elapsed time was 4.146217. @PatrickSharbaugh – That's me. Nov 14 '15 at 18:14
  • Can you fix this? – That's me. Nov 15 '15 at 13:24
  • [BOUNTY: +100] for an answer or edit to the following situation: "The GameObject jumps, reaches the target and stops moving like your code intends to. Now, when the GameObject reaches the target, the target must go to a higher position (for example, position.y += 50) and the GameObject jumps there. And the cycle continues... How can we write this is in code? Ask me if you've got any questions. –  Dec 30 '15 at 18:00
  • @PatrickSharbaugh If you want to complete your answer, read the bounty box. Good luck! ;) –  Jan 01 '16 at 15:14
  • @PatrickSharbaugh don't bother "completing" your answer. He just wants a complete solution to a simple problem again, really just wanting other people to write his game for him. Also, questions shouldn't be asked in bounties, so.... yeah. If he actually wants an "answer", he should ask a new question. – Pip Jan 03 '16 at 14:29