***Title: Knockback Only Working Vertically***

Message:

Hello everyone,

I’m currently working on a 2D game in Unity and I have encountered an issue with my knockback mechanic. When the player is hit by an enemy, they only experience knockback in the upward direction and not in the horizontal (X) direction.

Here is the relevant part of my code:
///
///
///

using System;
using System.Collections;
using UnityEngine;


public class PlayerMoment : MonoBehaviour
{
    //Movment Variabels
    
    [Header("Horizontal Movment Settings")]
    public float moveSpeed;
    private float moveDirectionX; 
    private float moveDirectionY; 
    [Header("Knockback-System")]
    [SerializeField] private float knockbackPower;
    private float knockbackPowerX = 2f;
    private float knockbackPowerY = 1.5f; 

    [Header("Jump Settings Player")]
    [SerializeField] public float JumpForce; 
    [SerializeField] private Transform groundCheck;
    [SerializeField] private float groundCheckY = 0.2f; 
    [SerializeField] private LayerMask WhatIsGround;  
    [SerializeField] private float groundCheckX;   

    [Header("Importan-System")]
    //Importent Values
    public Rigidbody2D rb; 
    Animator anim; 
    private TrailRenderer _trailRenderer; 
    public GameObject BarsPosition; 



    void Start()
    {
        rb = GetComponent<Rigidbody2D>(); 
        anim = GetComponent<Animator>(); 
        _trailRenderer = GetComponent<TrailRenderer>();  
        
    }

  
    void Update()
    {

        GetInput();
        Move();
        Jump();
        Flip(); 

    }

    public void KnockbackSystem(Collision2D collision)
    {
        if(collision.gameObject.CompareTag("BarsEnemy")) // Verwende CompareTag für bessere Leistung
        {
            Debug.Log("Wurde getroffen");

            float direction = Mathf.Sign(transform.position.x - BarsPosition.transform.position.x);
            Vector2 knockbackForce = new Vector2(direction * knockbackPowerX, knockbackPowerY * knockbackPower);
            rb.AddForce(knockbackForce, ForceMode2D.Impulse); 
            // rb.velocity = Vector2.zero; 
            
        } 
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        KnockbackSystem(collision); 
    }

    void GetInput()
    {
        moveDirectionX = Input.GetAxisRaw("Horizontal"); 
        moveDirectionY = Input.GetAxisRaw("Vertical"); 
    }

    //Methode for walking
    void Move()
    {
        rb.velocity = new Vector2(moveSpeed * moveDirectionX, rb.velocity.y); 
        anim.SetBool("isWalking", rb.velocity.x != 0 && Grounded()); 
    }


    void Flip()
    {
        if(moveDirectionX < 0)
        {
            transform.localScale = new Vector2(-4, transform.localScale.y); 
        }
        else if(moveDirectionX > 0)
        {
            transform.localScale = new Vector2(4, transform.localScale.y); 
        }
    }

    public bool Grounded()
    {
        if(Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckY, WhatIsGround)
            ||Physics2D.Raycast(groundCheck.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, WhatIsGround)
            ||Physics2D.Raycast(groundCheck.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, WhatIsGround))      
        {
            return true; 
        }
        else 
        {
            return false; 
        }  
    } 
 
    private void Jump()
    {
        if(Input.GetButtonUp("Jump") && ( rb.velocity.y > 0))
        {
            rb.velocity = new Vector2(rb.velocity.x, 0);
            
        }
        if(Input.GetButtonDown("Jump") && Grounded())
        {
             rb.velocity = new Vector3(rb.velocity.x, JumpForce);
        }
        if(rb == !Grounded())
        {
           
        }
        anim.SetBool("isJumping", !Grounded() || Input.GetButtonDown("Jump"));
    }

    void OnDrawGizmos()
    {
        Gizmos.color = Color.red; // Setze die Farbe auf rot
        Gizmos.DrawWireSphere(groundCheck.position, groundCheckY); // Zeichne die Gizmo-Sphäre
    }

      
}

///
///
///
Despite calculating the direction for knockback based on the enemy’s position, the player only moves upwards upon impact. I have verified my gravity settings and other mechanics, but the horizontal knockback still doesn’t work.

Has anyone else faced a similar issue or have suggestions on how to resolve this? Any help would be greatly appreciated!

Thank you!

Line 82 is always setting the X velocity so horizontal knockback is immediately eliminated.

Usually a timer and some sort of blend-in-blend-out is used for knockbacks.

1 Like

Thank you so much for your help, Brother! I have resolved the issue and now understand why I was experiencing these problems. I’ve updated my code, and it’s working perfectly now:

csharp

Code kopieren

using System.Collections;
using UnityEngine;

public class PlayerMoment : MonoBehaviour
{
    // Movement Variables
    [Header("Horizontal Movement Settings")]
    public float moveSpeed;
    private float moveDirectionX; 
    private float moveDirectionY; 

    [Header("Knockback-System")]
    [SerializeField] private float knockbackPower;
    private float knockbackPowerX = 2f;
    private float knockbackPowerY = 1.5f; 
    private bool isKnockedBack = false; // New variable for knockback

    [Header("Jump Settings Player")]
    [SerializeField] public float JumpForce; 
    [SerializeField] private Transform groundCheck;
    [SerializeField] private float groundCheckY = 0.2f; 
    [SerializeField] private LayerMask WhatIsGround;  
    [SerializeField] private float groundCheckX;   

    [Header("Important-System")]
    // Important Values
    public Rigidbody2D rb; 
    Animator anim; 
    private TrailRenderer _trailRenderer; 
    public GameObject BarsPosition; 

    void Start()
    {
        rb = GetComponent<Rigidbody2D>(); 
        anim = GetComponent<Animator>(); 
        _trailRenderer = GetComponent<TrailRenderer>();  
    }

    void Update()
    {
        if (!isKnockedBack) // Check if the player is not in knockback
        {
            GetInput();
            Move();
            Jump();
            Flip(); 
        }
    }

    public void KnockbackSystem(Collision2D collision)
    {
        if(collision.gameObject.CompareTag("BarsEnemy")) // Use CompareTag for better performance
        {
            Debug.Log("Hit!");

            float direction = Mathf.Sign(transform.position.x - BarsPosition.transform.position.x);
            Vector2 knockbackForce = new Vector2(direction * knockbackPowerX, knockbackPowerY * knockbackPower);
            rb.AddForce(knockbackForce, ForceMode2D.Impulse); 
            
            isKnockedBack = true; // Set knockback status
            StartCoroutine(ResetKnockback()); // Start coroutine to reset knockback status
        } 
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        KnockbackSystem(collision); 
    }

    void GetInput()
    {
        moveDirectionX = Input.GetAxisRaw("Horizontal"); 
        moveDirectionY = Input.GetAxisRaw("Vertical"); 
    }

    // Method for walking
    void Move()
    {
        rb.velocity = new Vector2(moveSpeed * moveDirectionX, rb.velocity.y); 
        anim.SetBool("isWalking", rb.velocity.x != 0 && Grounded()); 
    }

    void Flip()
    {
        if(moveDirectionX < 0)
        {
            transform.localScale = new Vector2(-4, transform.localScale.y); 
        }
        else if(moveDirectionX > 0)
        {
            transform.localScale = new Vector2(4, transform.localScale.y); 
        }
    }

    public bool Grounded()
    {
        return Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckY, WhatIsGround)
            || Physics2D.Raycast(groundCheck.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, WhatIsGround)
            || Physics2D.Raycast(groundCheck.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, WhatIsGround);  
    } 

    private void Jump()
    {
        if(Input.GetButtonUp("Jump") && ( rb.velocity.y > 0))
        {
            rb.velocity = new Vector2(rb.velocity.x, 0);
        }
        if(Input.GetButtonDown("Jump") && Grounded())
        {
             rb.velocity = new Vector2(rb.velocity.x, JumpForce);
        }
        anim.SetBool("isJumping", !Grounded() || Input.GetButtonDown("Jump"));
    }

    private IEnumerator ResetKnockback()
    {
        yield return new WaitForSeconds(0.5f); // Wait for 0.5 seconds
        isKnockedBack = false; // Reset knockback status
    }

    void OnDrawGizmos()
    {
        Gizmos.color = Color.red; // Set color to red
        Gizmos.DrawWireSphere(groundCheck.position, groundCheckY); // Draw the Gizmo sphere
    }
}

Now it’s working perfectly! I really appreciate your guidance.

1 Like