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. Dismiss Notice

Question Need help fixing my 2D player knockback script

Discussion in 'Scripting' started by DTheChemist, Aug 31, 2023.

  1. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    Need help. Hello all

    I want the knock back to happen to the player on either side of the enemy. for now it only activates when he either jumps on the enemy or walk into the enemy from the left side. Obviously i want it to activate the player knock back from the right, top and left side of the enemy. Keep in mind its a 2D platformer style like castlevania so im trying to recreate that same knock back damage effect from those old games




    This is as far as i got with the code that makes the knock back code touching the left side of the enemy to activate the effect:




    Code (CSharp):
    1.  
    2.  
    3.  
    4.  
    5.     float hit = 4500f;
    6.     public float knockbackForce = 10f;
    7.     public float knockbackDuration = 0.5f;
    8.  
    9.     public bool isKnockback = false;
    10.     private Vector2 knockbackDirection;
    11.  
    12.  
    13. private void OnTriggerEnter2D(Collider2D collision)
    14.     {
    15.         if (collision.gameObject.CompareTag("Enemy"))
    16.         {
    17.             TakeDamage(10);
    18.             StartCoroutine(KnockbackCoroutine());
    19.          
    20.         }
    21.     }
    22.  
    23.  
    24.   IEnumerator KnockbackCoroutine()
    25.     {
    26.         isKnockback = true;
    27.         Vector2 difference = (transform.position - Enemy.transform.position).normalized;
    28.         Vector2 force = difference * knockbackForce;
    29.         rb.AddForce(-transform.right * hit);
    30.         rb.AddForce(force, ForceMode2D.Impulse);
    31.  
    32.         yield return new WaitForSeconds(knockbackDuration);
    33.  
    34.         isKnockback = false;
    35.     }
    36.  
    37.  
    38.  
    39.  


    What am i missing for the full effect touching any side of the enemy to get knock back?
     
    Last edited: Aug 31, 2023
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    You just need a direction from the player to the enemy. How to do this is outlined in the documentation: https://docs.unity3d.com/Manual/VectorCookbook.html

    So when you collider with an enemy, just get said direction, and the reverse of that direction is the direction to not the player back towards.
     
    Kurt-Dekker likes this.
  3. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    Ill be honest with you. I learn slow at this stuff right now and i use either examples to learn or watch step by step tutorials to get as far as i did. What i do know is rb.AddForce(-transform.right * hit); is what got me the partial results

    Im seeing it saying Vector3 and im using Vector2. I thought Vector3 was only for 3D stuff? So im lost by reading all that math. If you could show me what you would do to alter what i did a bit to give me the result im looking for id appreciate it. That doc is just showing a lot of math and making me over think my entire code. if its a small fix id like to visually see the example. thats all.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    All of Unity is technically 3d. Even 2d objects exist in 3d space in Unity, and all have a transform component with a Vector3 (3d) position. Vector2 is just when you only need to do calculations that operate on a 2d plane, but pretty much 100% of the principles with Vector3 apply to Vector2, the only difference being the latter lacks a z component.

    The important line is this:
    Code (CSharp):
    1. var c = b - a;
    Or in more english terms:

    Code (CSharp):
    1. Vector3 direction = targetPosition - currentPosition;
    So when your enemy enacts your trigger, you get can this direction, and just pass it to your co-routine method. I think the issue here is your calculation for
    difference
    is backwards.

    It should be as simple as:
    Code (CSharp):
    1. private void OnTriggerEnter2D(Collider2D collision)
    2. {
    3.     if (collision.gameObject.CompareTag("Enemy"))
    4.     {
    5.         Vector3 direction = -(collision.transform.position - this.transform.position).normalized;
    6.      
    7.         TakeDamage(10);
    8.         StartCoroutine(KnockbackCoroutine(direction));  
    9.     }
    10. }
    11.  
    12.  
    13. IEnumerator KnockbackCoroutine(Vector3 direction)
    14. {
    15.     isKnockback = true;
    16.     Vector3 force = direction * knockbackForce;
    17.     rb.AddForce(force, ForceMode2D.Impulse);
    18.  
    19.     yield return new WaitForSeconds(knockbackDuration);
    20.  
    21.     isKnockback = false;
    22. }
     
    Last edited: Aug 31, 2023
  5. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    With the changes it took way the partial knockback effect entirely i had before. But thats fine though. what you explained made me jarred my memory on something else which triggers get hit from both sides from an old Unity Megaman game script.


    Thanks anyway!
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    I'm not sure what 'partial' knockback means, but it should work in pushing the player away from the enemy.
     
  7. DTheChemist

    DTheChemist

    Joined:
    Jan 18, 2021
    Posts:
    115
    when you removed this..... rb.AddForce(-transform.right * hit);

    the mild effect i had before was gone as well.

    i was using float hit = 4500f;

    &

    rb.AddForce(-transform.right * hit);


    I did a test with what your post suggested and nothing was happening at all anymore. I guess its something else i dont see
     
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    That will only ever apply a huge force for one physics frame in the one direction upon contact. If you're trying to mitigate the force of the knockback... just apply less force? Or at the very least, apply it in the opposite direction of your knockback, rather than a static direction.