Forum begins after the advertisement:


[General] Enemy doesn’t take damage and gets pushed by the player.

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [General] Enemy doesn’t take damage and gets pushed by the player.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #13374
    demilade
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    PlayerController attack code

    [Header("Attack Settings:")]
        [SerializeField] private Transform SideAttackTransform; 
        [SerializeField] private Vector2 SideAttackArea; 
        [SerializeField] private Transform UpAttackTransform; 
        [SerializeField] private Vector2 UpAttackArea; 
        [SerializeField] private Transform DownAttackTransform; 
        [SerializeField] private Vector2 DownAttackArea;
        [SerializeField] LayerMask AttackableLayer;
        [SerializeField] private float Damage;
        private bool attack = true;
        private float TimeBetweenAttack;
        private float TimeSinceAttack;
        [Space(5)]
    void Attack()
        {
            TimeSinceAttack += Time.deltaTime;
            if(attack && TimeSinceAttack >= TimeBetweenAttack)
            {
                TimeSinceAttack = 0;
                anim.SetTrigger("Attacking");
    
                if(yAxis == 0 || yAxis < 0 && Grounded ==true)
                {
                    Hit(SideAttackTransform, SideAttackArea);
                }
                else if(yAxis > 0)
                {
                    Hit(UpAttackTransform, UpAttackArea);
                }
                else if (yAxis < 0 && !Grounded == true)
                {
                    Hit(DownAttackTransform, DownAttackArea);
                }          
            }
        }
    
        void Hit(Transform _attackTransform, Vector2 _attackArea)
        {
            Collider2D[] objectsToHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, AttackableLayer);
    
            for (int i = 0; i < objectsToHit.Length; i++)
            {
                if (objectsToHit[i].GetComponent<Enemy>() != null)
                {
                    objectsToHit[i].GetComponent<Enemy>().EnemyHit(Damage);
                }
            }
        }

    Enemy code

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Enemy : MonoBehaviour
    {
        [SerializeField] protected float Health;
        [SerializeField] protected float speed;
        // Start is called before the first frame update
        protected virtual void Start()
        {
    
        }
    
        // Update is called once per frame
        protected virtual void Update()
        {
            if(Health <= 0)
            {
                Destroy(gameObject);
            }
        }
    
        public virtual void EnemyHit(float _damageDone)
        {
            Health -= _damageDone;
        }   
    }

    I also used a different sprite for my character. I dont know whether that matters

    #13377
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    What layer is your enemy on, and what does the Attackable Layer on your Player Controller look like?

    #13422
    demilade
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    Fixed the damage issue but i still push the enemy away when I come in contact with them. The enemy also pushes me.

    Player code

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PlayerController : MonoBehaviour
    {
        [Header("Horizontal Movement Settings:")]
        [SerializeField] private float WalkSpeed = 1;
        [Space(5)]
    
        [Header("Vertical Movement Settings")]
        [SerializeField] private float JumpForce = 45;
        [SerializeField] private int JumpBufferFrames;
        [SerializeField] private float CoyoteTime;
        [SerializeField] private int MaxAirJumps = 1;
        private int JumpBufferCounter = 0;
        private float CoyoteTimeCounter = 0;
        private int AirJumpCounter = 0;
        private float Gravity;
        public bool Grounded;
        [Space(5)]
    
        [Header("Dash Settings")]
        [SerializeField] private float DashSpeed;
        [SerializeField] private float DashTime;
        [SerializeField] private float DashCooldown;
        private bool CanDash = true;
        private bool Dashed = true; 
        [Space(5)]
    
        [Header("Attack Settings:")]
        [SerializeField] private Transform SideAttackTransform; 
        [SerializeField] private Vector2 SideAttackArea; 
        [SerializeField] private Transform UpAttackTransform; 
        [SerializeField] private Vector2 UpAttackArea; 
        [SerializeField] private Transform DownAttackTransform; 
        [SerializeField] private Vector2 DownAttackArea;
        [SerializeField] LayerMask AttackableLayer;
        [SerializeField] private float Damage;
        private bool attack = true;
        private float TimeBetweenAttack;
        private float TimeSinceAttack;
        [Space(5)]
    
        //References
        Rigidbody2D rb;
        private float xAxis;
        private float yAxis;
        private Animator anim;
        private PlayerStateList PState;
    
        public static PlayerController Instance;
    
        void Start()
        {
            rb = GetComponent<Rigidbody2D>();
            anim = GetComponent<Animator>();
            PState = GetComponent<PlayerStateList>();
            Gravity = rb.gravityScale;
        }
    
        void Update()
        {
            GetInputs();
            UpdateJumpVariables();
    
            if (PState.dashing) return;
            Move();
            Jump();
            Flip();
            StartDash();
            Attack();
        }
    
        void GetInputs()
        {
            xAxis = Input.GetAxisRaw("Horizontal");
            attack = Input.GetMouseButtonDown(0);
            yAxis = Input.GetAxisRaw("Vertical");
        }
    
        void Move()
        {
            rb.velocity = new Vector2(WalkSpeed * xAxis, rb.velocity.y);
    
            anim.SetBool("Walking", rb.velocity.x != 0 && Grounded == true);
        }
    
        void Jump()
        {
            if(Input.GetButtonUp("Jump") && rb.velocity.y > 0)
            {
                PState.jumping = false;
    
                rb.velocity = new Vector2(rb.velocity.x, 0);
            }
    
            if (!PState.jumping)
            {
              if (JumpBufferCounter > 0 && CoyoteTimeCounter > 0)
              {
                PState.jumping = true;
    
                rb.velocity = new Vector3(rb.velocity.x, JumpForce);
              }
                else if (!Grounded == true && AirJumpCounter < MaxAirJumps && Input.GetButtonDown("Jump"))
                {
                    PState.jumping = true;
    
                    AirJumpCounter++;
    
                    rb.velocity = new Vector3(rb.velocity.x, JumpForce);
                }
            }
    
            anim.SetBool("Jumping", !Grounded == true);
        }
    
         void UpdateJumpVariables()
        {
            if (Grounded == true)
            {
                CoyoteTimeCounter = CoyoteTime;
    
                PState.jumping = false;
    
                AirJumpCounter = 0;
            }
            else
            {
                CoyoteTimeCounter -= Time.deltaTime;
            }
    
            if (Input.GetButtonDown("Jump"))
            {
                JumpBufferCounter = JumpBufferFrames;
            }
            else
            {
                JumpBufferCounter--;
            }
        }  
    
        private void OnCollisionEnter2D(Collision2D other)
        {
            if (other.gameObject.CompareTag("Floor"))
            {
                Grounded = true;
            }
        }
    
        private void OnCollisionExit2D(Collision2D other)
        {
            if (other.gameObject.CompareTag("Floor"))
            {
                Grounded = false;
            }
        }
    
        void Flip()
        {
            if (xAxis < 0)
            {
                transform.localScale = new Vector2(-1, transform.localScale.y);
            }
            else if (xAxis > 0)
            {
                transform.localScale = new Vector2(1, transform.localScale.y);
            }
        }
    
        private void Awake()
        {
            if(Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
        }
    
        IEnumerator Dash()
        {
            CanDash = false;
            PState.dashing = true;
            anim.SetTrigger("Dashing");
            rb.gravityScale = 0;
            rb.velocity = new Vector2(transform.localScale.x * DashSpeed, 0);
            print("Dash coroutine");
            yield return new WaitForSeconds(DashTime);
            rb.gravityScale = Gravity;
            PState.dashing = false;
            yield return new WaitForSeconds(DashCooldown);
            CanDash = true;
        }
    
        void StartDash()
        {
            if(Input.GetButtonDown("Dash") && CanDash && !Dashed)
            {
                StartCoroutine(Dash());
                Dashed = true;
            }
    
            if (Grounded == true)
            {
                Dashed = false;
            }
        }
    
        void Attack()
        {
            TimeSinceAttack += Time.deltaTime;
            if(attack && TimeSinceAttack >= TimeBetweenAttack)
            {
                TimeSinceAttack = 0;
                anim.SetTrigger("Attacking");
    
                if(yAxis == 0 || yAxis < 0 && Grounded ==true)
                {
                    Hit(SideAttackTransform, SideAttackArea);
                }
                else if(yAxis > 0)
                {
                    Hit(UpAttackTransform, UpAttackArea);
                }
                else if (yAxis < 0 && !Grounded == true)
                {
                    Hit(DownAttackTransform, DownAttackArea);
                }          
            }
        }
    
        void Hit(Transform _attackTransform, Vector2 _attackArea)
        {
            Collider2D[] objectsToHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, AttackableLayer);
    
            for (int i = 0; i < objectsToHit.Length; i++)
            {
                if (objectsToHit[i].GetComponent<Enemy>() != null)
                {
                    objectsToHit[i].GetComponent<Enemy>().EnemyHit(Damage);
                }
            }
        }
    
        private void OnDrawGizmos()
        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireCube(SideAttackTransform.position, SideAttackArea);
            Gizmos.DrawWireCube(UpAttackTransform.position, UpAttackArea);
            Gizmos.DrawWireCube(DownAttackTransform.position, DownAttackArea);
        }
    }

    Enemy code

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Enemy : MonoBehaviour
    {
        [SerializeField] protected float health;
        [SerializeField] protected float speed;
        protected Rigidbody2D rb;
    
        // Start is called before the first frame update
        protected virtual void Start()
        {
    
        }
    
        protected virtual void Awake()
        {
            rb = GetComponent<Rigidbody2D>();
        }
        // Update is called once per frame
        protected virtual void Update()
        {
            if (health <= 0)
            {
                Destroy(gameObject);
            }
        }
    
        public virtual void EnemyHit(float _damageDone)
        {
            health -= _damageDone;
        }
    }
    #13423
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Demilade, the enemy / player pushing is intended, because their movements are coded with Rigidbodies, and this is how Rigidbodies work. The simplest way to fix this is to make all your enemy Rigidbodies have a lot of mass, e.g. a Mass of 1000, so that the player cannot push them.

    Conversely, you can make the player have a lot of Mass instead so the enemies cannot push them around.

    If you want to make both parties be unable to push each other, you will need to modify your code to detect enemies / players and stop the movement. Here’s an example for the player:

    
        void Move()
        {
            rb.velocity = new Vector2(WalkSpeed * xAxis, rb.velocity.y);
    
            // Zero out the velocity if there is something in the way of where we are moving.
            if(Physics2D.Raycast(transform.position, Vector2.right * xAxis))
                rb.velocity = Vector2.zero;
    
            anim.SetBool("Walking", rb.velocity.x != 0 && Grounded == true);
        }
Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: