Forum begins after the advertisement:
[Part 3] Player not taking damage
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 3] Player not taking damage
- This topic has 7 replies, 3 voices, and was last updated 12 months ago by Terence.
-
AuthorPosts
-
December 4, 2023 at 3:21 pm #12497::
hello I’m having trouble with the last part of video#3 my player does not take any damage even if I have 2 box collider and one is set to trigger. I have also added the player object in the enemy but nothing happened.
`code:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { [Header("movement setting")] [SerializeField] private float walkSpeed = 1; [SerializeField] private float jumpHeight = 50f; [SerializeField] private float jumpHeight2 = 15f; [SerializeField] private int jumpFrames; [SerializeField] private float CT; [SerializeField] private int Maxdjump; private float CTC; private int JBC = 0; private int djumpcounter = 0; [Header("Ground check setting")] [SerializeField] private Transform groundCheck; [SerializeField] private float GroundCheckY = 0.2f; [SerializeField] private float GroundCheckX = 0.5f; [SerializeField] private LayerMask WIG; [Header("dash")] private bool candash; private bool dashed; [SerializeField] private float dashSpeed; [SerializeField] private float dashTime; [SerializeField] private float dashCD; [Header("Attacking")] [SerializeField] Transform sAttack; [SerializeField] Transform uAttack; [SerializeField] Transform dAttack; [SerializeField] Vector2 sAttackArea; [SerializeField] Vector2 uAttackArea; [SerializeField] Vector2 dAttackArea; [SerializeField] LayerMask Attackablelayer; [SerializeField] float damage; bool attack = false; float TBA; float TSA; [Header("Recoil")] [SerializeField] int recoilStepx = 5; [SerializeField] int recoilStepy = 5; [SerializeField] float recoilSpeedx = 100; [SerializeField] float recoilSpeedy = 100; int stepedXrecoiled; int stepedYrecoiled; [Header("Plyaer Hp")] public int health; public int MaxPlayerHp; private float xAxis, yAxis; private Rigidbody2D rb; [HideInInspector]public playerState pState; public static PlayerController instance; Animator anim; private float gravity; private void Awake() { if (instance != null && instance != this) { Destroy(gameObject); } else { instance = this; } health = MaxPlayerHp; } void Start() { pState = GetComponent<playerState>(); rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); gravity = rb.gravityScale; } private void OnDrawGizmos() { Gizmos.color = Color.green; Gizmos.DrawWireCube(sAttack.position, sAttackArea); Gizmos.DrawWireCube(uAttack.position, uAttackArea); Gizmos.DrawWireCube(dAttack.position, dAttackArea); } void Update() { GetInput(); UpdateJumpVar(); if (pState.dashing) return; Move(); Jump(); flip(); startdash(); Attack(); recoil(); } void GetInput() { xAxis = Input.GetAxisRaw("Horizontal"); yAxis = Input.GetAxisRaw("Vertical"); attack = Input.GetMouseButtonDown(0); } void flip() { if (xAxis < 0) { transform.localScale = new Vector2(-1, transform.localScale.y); pState.islookingright = false; } else if (xAxis > 0) { transform.localScale = new Vector2(1, transform.localScale.y); pState.islookingright = true; } } private void Move() { rb.velocity = new Vector2(walkSpeed * xAxis, rb.velocity.y); anim.SetBool("isrunning", rb.velocity.x != 0 && Grounded()); } void startdash() { if (Input.GetButtonDown("Dash") && !dashed) { StartCoroutine(Dash()); dashed = true; } if (Grounded()) { dashed = false; } } IEnumerator Dash() { candash = false; pState.dashing = true; anim.SetTrigger("isdashing"); rb.gravityScale = 0; rb.velocity = new Vector2(transform.localScale.x * dashSpeed, 0); yield return new WaitForSeconds(dashTime); rb.gravityScale = gravity; pState.dashing = false; yield return new WaitForSeconds(dashCD); candash = true; } void Attack() { TSA += Time.deltaTime; if (attack && TSA >= TBA) { TSA = 0; anim.SetTrigger("isattacking"); if (yAxis == 0 || yAxis < 0 && Grounded()) { hit(sAttack, sAttackArea, ref pState.recoilingx, recoilSpeedx); } else if (yAxis > 0) { hit(uAttack, uAttackArea, ref pState.recoilingy, recoilSpeedy); } else if (yAxis < 0 && !Grounded()) { hit(dAttack, dAttackArea, ref pState.recoilingy, recoilSpeedy); } } } private void hit(Transform _attackTransform, Vector2 _attackArea, ref bool _recoilDir, float _recoilStrength) { Collider2D[] OHT = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, Attackablelayer); if(OHT.Length > 0) { _recoilDir = true; } for (int i = 0; i < OHT.Length; i++) { if (OHT[i].GetComponent<enemy>() != null) { OHT[i].GetComponent<enemy>().enemyhit (damage,(transform.position - OHT[i].transform.position).normalized, _recoilStrength); } } } void recoil() { if (pState.recoilingx) { if (pState.islookingright) { rb.velocity = new Vector2(-recoilSpeedx, 0); } else { rb.velocity = new Vector2(recoilSpeedx, 0); } } if (pState.recoilingy) { rb.gravityScale = 0; if (yAxis < 0) { rb.velocity = new Vector2(rb.velocity.x, recoilSpeedy); } else { rb.velocity = new Vector2(rb.velocity.x, -recoilSpeedy); } djumpcounter = 0; } else { rb.gravityScale = gravity; } if(pState.recoilingx && stepedXrecoiled < recoilStepx) { stepedXrecoiled++; } else { stoprecoilX(); } if (pState.recoilingy && stepedYrecoiled < recoilStepy) { stepedYrecoiled++; } else { stoprecoilY(); } if (Grounded()) { stoprecoilY(); } } void stoprecoilX() { stepedXrecoiled = 0; pState.recoilingx = false; } void stoprecoilY() { stepedYrecoiled = 0; pState.recoilingy = false; } public void TakeDamage(float _damage) { health -= Mathf.RoundToInt(_damage); ; StartCoroutine(StopTakingDamage()); } IEnumerator StopTakingDamage() { pState.invincible = true; anim.SetTrigger("takedamage"); clampHealth(); yield return new WaitForSeconds(2f); pState.invincible = false; } void clampHealth() { health = Mathf.Clamp(health, 0, MaxPlayerHp); } public bool Grounded() { if (Physics2D.Raycast(groundCheck.position, Vector2.down, GroundCheckY, WIG) || Physics2D.Raycast(groundCheck.position + new Vector3(GroundCheckX, 0, 0), Vector2.down, GroundCheckY, WIG) || Physics2D.Raycast(groundCheck.position + new Vector3(-GroundCheckX, 0, 0), Vector2.down, GroundCheckY, WIG)) { return true; } else { return false; } } 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 (JBC > 0 && CTC > 0) { pState.jumping = true; rb.velocity = new Vector2(rb.velocity.x, jumpHeight); } else if (!Grounded() && djumpcounter < Maxdjump && Input.GetButtonDown("Jump")) { pState.jumping = true; djumpcounter++; rb.velocity = new Vector2(rb.velocity.x, jumpHeight2); } } anim.SetBool("isjumping", !Grounded()); } void UpdateJumpVar() { if (Grounded()) { pState.jumping = false; CTC = CT; djumpcounter = 0; } else { CTC -= Time.deltaTime; } if (Input.GetButtonDown("Jump")) { JBC = jumpFrames; } else { JBC--; } } }
December 4, 2023 at 9:03 pm #12502::Hi Haydn, can you add the following line to
TakeDamage()
and see if the Console shows this message when the player gets hit?public void TakeDamage(float _damage) { Debug.Log("Player is taking damage."); health -= Mathf.RoundToInt(_damage);
;StartCoroutine(StopTakingDamage()); }You also have an extra
;
after the 2nd line. It’s highlighted in red above.December 4, 2023 at 9:19 pm #12503::i have added the Debug.Log(“Player is taking damage.”); and remove the extra ; but nothing happened
code for enemy:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class enemy : MonoBehaviour { [SerializeField] protected float hp; [SerializeField] protected float recoildistance; [SerializeField] protected float recoilF; [SerializeField] protected bool isrecoiling = false; [SerializeField] protected PlayerController player; [SerializeField] protected float speed; [SerializeField] protected float damage; protected float recoiltimer; protected Rigidbody2D rb; protected virtual void Start() { } protected virtual void Awake() { rb = GetComponent<Rigidbody2D>(); player = PlayerController.instance; } protected virtual void Update() { if (hp <= 0) { Destroy(gameObject); } if(isrecoiling ) { if(recoiltimer < recoildistance) { recoiltimer += Time.deltaTime; } else { isrecoiling = false; } } } public virtual void enemyhit(float _damagedone, Vector2 _hitdirection,float _hitforce) { hp -= _damagedone; if (!isrecoiling) { rb.AddForce(-_hitforce * recoilF * _hitdirection); } } protected void OnTriggerStay2D(Collider2D _other) { if (_other.CompareTag("Player") && !PlayerController.instance.pState.invincible) { Attack(); } } protected virtual void Attack() { PlayerController.instance.TakeDamage(damage); } }
December 4, 2023 at 9:19 pm #12504::code for enemy type
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Doll : enemy { void Start() { rb.gravityScale = 12f; } protected override void Awake() { base.Awake(); } protected override void Update() { base.Update(); if(!isrecoiling) { transform.position = Vector2.MoveTowards (transform.position, new Vector2(PlayerController.instance.transform.position.x, transform.position.y),speed * Time.deltaTime); } } }
December 4, 2023 at 9:34 pm #12505December 8, 2023 at 12:47 am #12547December 14, 2023 at 8:26 am #12649::I am stuck in the same part, but I didn’t solve it by deleting the line of code from the player tag, how can I solve it? In the debug it appears that it receives damage and changes the animation, but in the inspector the subtracted damage does not appear, it remains at 10, I would like to know a solution, I am very excited about the tutorial, very complete
December 14, 2023 at 12:55 pm #12655::Hi Yanko, thank you.
Haydn didn’t remove the Player tag. He tagged the Player GameObject with the Player tag and got it to work.
View post on imgur.com
Let me know if doing this works for you.
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: