Search Unity

ForceMode2D.Impulse inconsistent

Discussion in '2D' started by Adjaar7, Aug 18, 2020.

  1. Adjaar7

    Adjaar7

    Joined:
    Jan 6, 2020
    Posts:
    22
    I am learning through making a 2D platformer and I want the character to launch into the air when they jump on an enemy's head. I've had the most luck with forcemode2D but I've also tried MovePosition, which did not perform well at all. I can't use Rigidbody2D.velocity because the character is not kinematic.

    The problem with ForceMode2D.Impulse is that it is inconsistent. Sometimes I land on the enemy and shoot straight into the air really high, and other times I barely get any air and I don't know why. Here is a link to see what I'm dealing with: https://imgur.com/a/7yGSWhF

    I'm looking at the API and not understanding what I should be doing different. If ForceMode2D is not the best way to do this, I would love to hear another way, but currently its the only way I can get close to what I want.

    Here is the relevant code:
    public float moveSpeed = 5f;
    public float idleDirection;
    public float jumpHeight = 10f;
    public float enemyBoost = 13f;
    public bool isGrounded = false;
    public Rigidbody2D rb;

    void Update()
    {
    Jump();
    Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0, 0f);
    transform.position += movement * Time.deltaTime * moveSpeed;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {

    if (collision.gameObject.CompareTag("WeakPoint")) //detects if player jumped on enemy's head
    {
    Destroy(collision.transform.parent.gameObject);
    gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, enemyBoost), ForceMode2D.Impulse);

    animator.SetTrigger("Jump");
    animator.SetBool("Jump Check", false);
    }
    }

    void Jump()
    {
    if (Input.GetButtonDown("Jump") && isGrounded == true)
    {
    gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpHeight), ForceMode2D.Impulse);
    animator.SetTrigger("Jump");
    animator.SetBool("Jump Check", true);

    }

    }
    }
     
  2. Teaky

    Teaky

    Joined:
    Oct 14, 2013
    Posts:
    7
    Even though your rigidbody2D isn't kinematic you can still use rigidbody2d.velocity. When I jump on the enemy I set the velocity to 0 -> gameObject.GetComponent<Rigidbody2D>().velocity = Vector2.zero. Based on your video I'm not sure that this will necessarily fix your issue but it will allow for a more consistent height when jumping.

    The other issue that can cause this, and it looks like this may be what is happening, is if OnTriggerEnter2D is being called more than once (can check this by making an int and incrementing it each time OnTriggerEnter2D is called). Also my logic for detecting this is on the enemy so I can set a bool that will change to true when the player jumps on its head that can ensure that the function in OnTriggerEnter2D only runs once. I don't know if it's a bug, but after a certain Unity update I noticed that I was getting this a lot so all of my OnTriggerEnter2D functions have some sort of logic to test if the collision has already occurred before running the rest of the code. Not an expert programmer so may be a more elegant solution, but I've found this works for me.
     
    duenda and Adjaar7 like this.
  3. Adjaar7

    Adjaar7

    Joined:
    Jan 6, 2020
    Posts:
    22
    Teaky I believe you are correct! I put a counter on and when it is a normal jump it is only detecting once, but when it is higher it is checking it twice. Now I understand the problem and am working on a fix! Thanks!