Can't get my enemy to jump correctly.

Hi all,

First time making a game/making a thread here, and I honestly wasn’t sure if this was more of a Physics question or a Scripting question, so forgive me if I messed this up.

Anyway, I’m trying to make a sidescroller with 3D characters in a 2D environment, and my first enemy is supposed to move by jumping towards the player (kind of like a rabbit) whenever the player enters its collider. So far so good, but whenever my enemy jumps, he flies up and diagonally into the sky, hits a certain point, and then falls straight to the ground. Now, I should let you know that I set my gravity to -30, and my player’s jump works perfectly fine, as you can see in the video I posted. However, my enemy, despite having seemingly the exact same component settings and jump physics as my main character, jumps way higher, way faster, and doesn’t jump in an arc. Here’s my enemy’s AI script, please let me know if you have any ideas!

using UnityEngine;
using System.Collections;

public class GrounderMovement : MonoBehaviour
{

    public float jumpSpeed = 600.0f;
    private Animator grounderAnim;
    bool canFlip = true;
    bool facingLeft = true;

    public bool grounderGrounded = false;
    public Transform GrounderGroundCheck;
    public float groundRadius = 0.2f;
    public LayerMask whatIsGround;
    public float jumpTime;
    float startJumpTime;
    bool jumping;
    Rigidbody grounderRB;

    // Use this for initialization
    void Start ()
    {
        grounderAnim = GetComponent<Animator> ();
        grounderRB = GetComponent<Rigidbody> ();
    }

    void FixedUpdate()
    {
        grounderGrounded = Physics2D.OverlapCircle (GrounderGroundCheck.position, groundRadius, whatIsGround);

        grounderAnim.SetBool ("grounderGrounded", grounderGrounded);
    }
    // Update is called once per frame
    void Update ()
    {

    }

    void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Player")
        {
            if (!facingLeft && other.transform.position.x < transform.position.x && grounderGrounded)
            {
                Flip ();
            }
            else if (facingLeft && other.transform.position.x > transform.position.x && grounderGrounded)
            {
                Flip ();
            }
            canFlip = false;
            jumping = true;
            grounderAnim.SetBool ("isJumping", jumping);
            startJumpTime = Time.time + jumpTime;
        }
    }

    void OnTriggerStay(Collider other)
    {
        if (other.tag == "Player")
        {
            if (startJumpTime < Time.time)
            {
                if (facingLeft)
                {
                    grounderGrounded = false;
                    jumping = false;
                    grounderAnim.SetBool ("grounderGrounded", grounderGrounded);
                    grounderAnim.SetBool ("isJumping", jumping);
                    grounderRB.AddForce (new Vector2 (-1, jumpSpeed));
                }
                else
                {
                    grounderGrounded = false;
                    jumping = false;
                    grounderAnim.SetBool ("grounderGrounded", grounderGrounded);
                    grounderAnim.SetBool ("isJumping", jumping);
                    grounderRB.AddForce (new Vector2 (1, jumpSpeed));
                }
            }
        }
    }

    void OnTriggerExit(Collider other)
    {
        if (other.tag == "Player")
        {
            canFlip = true;
            jumping = false;
            grounderRB.velocity = Vector2.zero;
            grounderAnim.SetBool ("isJumping", jumping);
        }
    }

    void Flip()
    {
        if (!canFlip)
        {
            return;
        }
        facingLeft = !facingLeft;

        transform.Rotate (Vector3.up, 180.0f, Space.World);
    }
}

2759822–199218–GrounderMovement.cs (2.21 KB)

Have you tried just using an impulse force instead?

grounderRB.AddForce(new Vector2(-1, jumpSpeed), ForceMode.Impulse); //jumpSpeed will need to be lowered

I think the startJumpTime system you’re using is a bit iffy. A jump force is perceived as instantaneous, so it should only need to be applied once. This way you could remove all of the OnTriggerStay() logic, and it would likely fix your problem.

Edit: Fixed a weird error in the line above.

1 Like

I’d use Rigidbody.AddForce(). To jump you should apply a force once. I really don’t see why you’re making things so much more difficult for yourself. Also you can look in the Standard Assets to see how Unity did a jumping person script.