Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Enemy takes knockback - with no knockback code.

Discussion in '2D' started by Seshua, Dec 18, 2022.

  1. Seshua

    Seshua

    Joined:
    Dec 31, 2017
    Posts:
    10
    Hello,

    For context I'm making a Top-Down Action shooter.

    I have a Enemy script and a Projectile script. The enemy script applies a movement method that makes it move towards the player automatically. The Projectile script handles just a basic projectile being shot from the player towards the mouse position, and when It comes into contact with the enemy it's supposed to deal damage and disappear. It does what its intended to do, except on my Larger enemies it knocks them back indefinitely. Not sure what is causing this. The Rigidbody2D on the enemies have varied Masses, the largest enemies have 150 mass. The projectile's mass is always 1. I thought the line rb.velocity = Vector3.zero; would be the solution but it doesn't prevent this from happening, without it they do go flying away. There's nothing in the Projectile code that applies any kind of force to external objects, just to the bullet itself for obvious reasons.

    Enemy: Gets called in FixedUpdate()
    Code (CSharp):
    1.  
    2. protected virtual void DoMovement()
    3.     {
    4.         if (Vector2.Distance(transform.position, target.position) < distanceToTheTarget)
    5.         {
    6.             transform.position = Vector2.MoveTowards(transform.position, target.position, moveSpeed * Time.deltaTime);
    7.         }
    8.         rb.velocity = Vector3.zero;
    9.     }
    10.  
    Projectile:
    Code (CSharp):
    1.  
    2.  private void OnCollisionEnter2D(Collision2D collision)
    3.     {
    4.         if (collision.gameObject.CompareTag("Enemy"))
    5.         {
    6.             if (collision.gameObject.CompareTag("XPToken")) return;
    7.  
    8.             collision.gameObject.GetComponent<Enemy>().TakeDamage();
    9.             GameObject effect = Instantiate(hitEffect, transform.position, Quaternion.identity);
    10.             Destroy(effect, 1.0f);
    11.             Destroy(gameObject);
    12.         }
    13.  
    14.     }
    15.  
     
    Last edited: Dec 18, 2022
  2. Seshua

    Seshua

    Joined:
    Dec 31, 2017
    Posts:
    10
    After some fiddling with the Rigidbody2D, I found that the Linear drag fixes the problem. It's just not what I'm trying to do though. I don't have the system yet, but I eventually want to implement a knockback resistance system. I want it to be done programmatically. I just don't understand how the enemy can take knockback at all when there's no code that says to do that. I'm guessing it's in the backend of the physics engine.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,954
    This is likely because you are bypassing the physics system and "startling" it, causing it to have to make massive adjustments to figure things out.

    This kind of line is the problem:

    With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.

    Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.

    https://forum.unity.com/threads/col...-unity-physic-rigidbody.1216875/#post-7763061

    https://forum.unity.com/threads/oncollisionenter2d-not-being-called.1266563/#post-8044121
     
  4. Seshua

    Seshua

    Joined:
    Dec 31, 2017
    Posts:
    10
    @Kurt-Dekker Thankyou for the info! Switching over to the rigidbody2d transform was definitely the right move.
     
    Kurt-Dekker likes this.