0
\$\begingroup\$

Currently I'm working on a 3D game. In this game my player is a ball and it can jump from tile to tile. The movement of the ball is 45 degrees left or right when it jumps. I want to make it jump in a parabolic path. But I'm unable to do that. I have used Mecanim, AngleAxis, and lerp as well. But the problem is when I use lerp and animation together, firstly the lerp works then the animation(Jump animation). Basically the ball has a parent and mainly the parent lerps between the tiles and the ball itself has the animation clip attached to it.

Any suggestions or help is appreciated.

\$\endgroup\$
1
\$\begingroup\$

Sounds like the problem is being over-complicated; this task can be achieved with Unity's built in physics and minimal amounts of code.

You can add a Rigidbody to the platforms and your player, enable useGravity on the player, enable isKinematic on the platforms, and then your script can simply call AddForce on the Rigidbody of the player.

You script could be as simple as this:

using UnityEngine;
using System.Collections;

public class Jumper : MonoBehaviour {

    public float m_jumpX;
    public float m_jumpY;

    private Rigidbody m_body;

    void Start () { 
        m_body = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            m_body.AddForce(new Vector3(m_jumpX, m_jumpY, 0.0f));
        }
    }
}

You'll want to make sure they can't jump while they're already in mid-air (which this script doesn't cover) but this should at least get you going in the right direction. If you handle movement like this with Mechanim or manually lerping values, you're going to be in for a mess down the line when you want to adjust seemingly simple things; might as well use the tech Unity has already written for you.

\$\endgroup\$
0
\$\begingroup\$

I had done something similar in XVR a year ago, it took me some time to convert it in C# as a component but here it is:

public class parable : MonoBehaviour {
    public float ANIMATION_DURATION = 2.0f;
    public float FRAMES_PER_SECOND = 30.0f;
    public GameObject one;
    public GameObject two;
    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }

    void OnDrawGizmos() {
        if(one != null && two != null){
            Gizmos.color = Color.yellow;
            Vector3[] points = parabolicMovement(one.transform.position, two.transform.position);
            foreach(Vector3 point in points){
                Gizmos.DrawSphere( point, .1f);
            }
        }
    }

    public Vector3[] parabolicMovement(Vector3 startingPos, Vector3 arrivingPos)
    {
        int framesNum = (int)(ANIMATION_DURATION * FRAMES_PER_SECOND);
        Vector3[] frames = new Vector3[framesNum];

        //PROJECTING ON Z AXIS
        Vector3 stP = new Vector3(0,startingPos.y,startingPos.z);
        Vector3 arP = new Vector3(0,arrivingPos.y,arrivingPos.z);

        Vector3 diff = new Vector3();

        Vector3 height = new Vector3(0,1,0);
        diff = ((arP-stP)/2) + height;
        Vector3 vertex = stP+diff;

        float x1 = startingPos.z;
        float y1 = startingPos.y;
        float x2 = arrivingPos.z;
        float y2 = arrivingPos.y;
        float x3 = vertex.z;
        float y3 = vertex.y;

        float denom = (x1 - x2)*(x1 - x3)*(x2 - x3);

        var z_dist = (arrivingPos.z - startingPos.z) / framesNum;
        var x_dist = (arrivingPos.x - startingPos.x) / framesNum;

        float A = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom;
        float B = (float)(System.Math.Pow(x3, 2) * (y1 - y2) + System.Math.Pow(x2, 2) * (y3 - y1) + System.Math.Pow(x1, 2) * (y2 - y3)) / denom;
        float C = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3) / denom;

        float newX = startingPos.z;
        float newZ = startingPos.x;

        for(int i = 0; i < framesNum; i++)
        {
            newX += z_dist;
            newZ += x_dist;
            float yToBeFound = A*(newX*newX)+ B*newX + C;
            frames[i] = new Vector3(newZ, yToBeFound, newX);
        }
        return frames;
    }
}

The idea behind this is to create a list of subsequential points that, once they get animated, will represent a parabolic movement. The main function here is parabolicMovement, taken two positions it creates a list of points (excluding the starting point) which is (ANIMATION_DURATION * FRAMES_PER_SECOND) long. The OnDraw Gizmos is there just to show the current result, you can also create an inspector on height by moving its declaration at the top of your component, is something I didn't need at that time. Hope this helps :)

\$\endgroup\$
2
  • \$\begingroup\$ Thank you so much @FreeFly. I got the idea. But could not convert the code to jump my player as I've very basic knowledge about Unity and C#. Can you please point out how can I use this to serve my purpose? No coding, just the concept please. Thanks \$\endgroup\$
    – rasel raaz
    Dec 2 '16 at 20:57
  • \$\begingroup\$ Sure @raselraaz! The idea behind parabolicMovement is to pre-calculate your movement before doing the real translation. Whenever you receive the input to move, calculate all the points of your movement through the function, and for each frame on your screen move your object to the next position. You can move it on every FixedUpdate function, but you could also use a Coroutine to do that! \$\endgroup\$
    – FreeFly
    Dec 2 '16 at 21:08

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.