Files
Crash-Course/Assets/Scripts/Player/Damageable.cs

137 lines
4.3 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Collider2D))]
[RequireComponent(typeof(RespawnOnTriggerEnter))]
public class Damageable : MonoBehaviour
{
public float force = 50f; // Force applied when hit
public float damage = 0f;
public float maxDamage = 1000f; // Set max health
public int lives = 0;
private Animator animator;
2025-03-07 10:46:30 -05:00
public bool damageSelfDebug = false;
public bool dying = false;
2025-03-17 18:20:03 -04:00
public event System.Action<GameObject> OnPlayerPunched;
2025-02-26 20:17:19 -05:00
private void Start()
{
animator = GetComponent<Animator>();
2025-02-26 20:17:19 -05:00
}
2025-03-07 10:46:30 -05:00
private void Update()
{
if (damageSelfDebug)
{
damageSelfDebug = false;
Damage(gameObject);
}
}
private void OnTriggerEnter2D(Collider2D collision) // Calls Damage method when player is hit
{
if (collision.gameObject.CompareTag("Punch Hurtbox"))
{
2025-02-09 17:18:51 -05:00
Damage(collision.transform.parent.gameObject);
}
}
private void Damage(GameObject damageSource) // Damages player
{
2025-03-28 23:07:33 -04:00
if (dying || damageSource.CompareTag("Hat")) return; // Exclude hat from taking damage
2025-03-07 17:30:04 -05:00
2025-03-07 10:46:30 -05:00
float actualForce = damageSource.GetComponent<Damageable>().force;
2025-02-26 20:17:19 -05:00
Block blockComponent = GetComponent<Block>();
2025-03-17 18:20:03 -04:00
GetComponentInChildren<UseItem>().DropItem(); // Drops hat if held
2025-03-17 18:20:03 -04:00
2025-03-28 23:07:33 -04:00
if (blockComponent != null && blockComponent.blocking)
2025-02-09 17:18:51 -05:00
{
if (blockComponent.IsParrying()) // Player receives damage if punching a parrying player
2025-02-26 20:17:19 -05:00
{
damageSource.GetComponent<Damageable>().SuccessfulParry(gameObject, actualForce);
return;
}
else // Player does less damage if punching a blocking player
2025-02-26 20:17:19 -05:00
{
actualForce /= 4;
GetComponent<Rigidbody2D>().AddForce(((transform.position - damageSource.transform.position).normalized + Vector3.up * 2) * actualForce, ForceMode2D.Force);
}
}
else // Player does full damage to a non-blocking player
2025-02-26 20:17:19 -05:00
{
2025-03-07 10:46:30 -05:00
GetComponent<Rigidbody2D>().AddForce(((transform.position - damageSource.transform.position).normalized + Vector3.up * 2) * actualForce * (1 + (damage / maxDamage) * 3), ForceMode2D.Force);
2025-02-09 17:18:51 -05:00
}
damage += actualForce;
2025-02-08 18:54:21 -05:00
damage = Mathf.Clamp(damage, 0f, maxDamage);
2025-02-26 20:17:19 -05:00
if (damage >= maxDamage)
{
Die();
}
}
public void Damage(float damage) // Adds damage to player when hit
2025-03-07 10:03:16 -05:00
{
2025-04-04 12:09:40 -04:00
if (GameManager.Instance.gameOver) return; // Prevent damage after game is over
2025-03-07 10:03:16 -05:00
this.damage += damage;
if (damage >= maxDamage)
{
Die();
}
}
2025-02-26 20:17:19 -05:00
private void SuccessfulParry(GameObject damageSource, float force)
{
GetComponent<Rigidbody2D>().AddForce(((transform.position - damageSource.transform.position).normalized + Vector3.up * 2) * force, ForceMode2D.Force);
damage += force;
damage = Mathf.Clamp(damage, 0f, maxDamage);
if (damage >= maxDamage)
{
Die();
}
}
private void Die() // Triggers death animation and sets player to dying state
2025-03-17 18:20:03 -04:00
{
2025-04-04 12:09:40 -04:00
if (GameManager.Instance != null && !GameManager.Instance.gameOver) // Prevent death after game is over
{
UseItem useItem = GetComponent<UseItem>();
if (useItem != null)
{
useItem.DropItem(); // Ensure the player drops the item before the death animation
}
2025-03-07 17:30:04 -05:00
animator.SetBool("die", true);
2025-03-07 10:46:30 -05:00
dying = true;
}
}
2025-03-03 18:55:03 -05:00
public void HandleDeath() // Removes player from dying state after respawn
{
2025-03-07 10:03:16 -05:00
GameManager.Instance.PlayerDied(this);
2025-03-07 17:30:04 -05:00
animator.SetBool("die", false);
2025-03-07 10:46:30 -05:00
dying = false;
2025-03-03 18:55:03 -05:00
}
public void Respawn() // Respawns player to the spawnPosition and resets damage/health bar
2025-03-03 18:55:03 -05:00
{
transform.position = GameManager.Instance.spawnPosition;
if (TryGetComponent<Rigidbody2D>(out var rb))
{
rb.linearVelocity = Vector2.zero;
rb.angularVelocity = 0f;
2025-03-03 18:55:03 -05:00
}
if (TryGetComponent<Damageable>(out var damageable))
{
damageable.ResetDamage();
}
}
public void ResetDamage()
{
damage = 0f;
}
}