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.
- This topic has 3 replies, 2 voices, and was last updated 9 months, 2 weeks ago by Terence.
-
AuthorPosts
-
February 21, 2024 at 8:22 am #13374::
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
February 21, 2024 at 11:14 pm #13377::What layer is your enemy on, and what does the Attackable Layer on your Player Controller look like?
February 28, 2024 at 6:43 pm #13422::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; } }
February 28, 2024 at 7:24 pm #13423::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); }
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: