CharacterClass.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public enum CharacterState { Idle, Moving, Attack, SpecialAttack, Dead } public class CharacterClass : MonoBehaviour { public int maxHealth; public int currentHealth; public int damage; public int lives = 3; public CharacterState currentState; public Animator animator; public CharacterMovement characterMovement; public Collider2D attackCollider; public GameOverTransition gameOverTransition; public HealthBar healthBar; public bool canAttack = true; private bool inCooldown = false; public float cooldownDuration = 5f; private float cooldownTimer = 0f; private List<Collider2D> cols = new List<Collider2D>(); private PlayerInput input; private CollectionManager collectionManager; private float speedMultiplier = 1f; private void Awake() { currentHealth = maxHealth; GameObject HPBar = GameObject.FindGameObjectWithTag("UI"); healthBar = HPBar.GetComponent<HealthBar>(); healthBar.SetMaxHealth(maxHealth); currentState = CharacterState.Idle; input = GetComponent<PlayerInput>(); attackCollider = GetComponent<BoxCollider2D>(); if (attackCollider == null) { attackCollider = GetComponentInChildren<BoxCollider2D>(); if (attackCollider == null) { Debug.LogError("BoxCollider2D component not found in the GameObject hierarchy."); } } collectionManager = FindObjectOfType<CollectionManager>(); characterMovement = GetComponent<CharacterMovement>(); } public void RegularAttack() { if (!inCooldown && input.controls.AttackState && canAttack) { Debug.Log("Attack Input Recieved"); animator.SetBool("Attack", true); StartCoroutine(EndAttackAnimationAfterDelay()); attackCollider.OverlapCollider(new ContactFilter2D(), cols); if (cols.Count > 0) { StartCooldown(); foreach (var col in cols) { EnemyClass enemyComponent = col.transform.root.GetComponentInChildren<EnemyClass>(); if (col.TryGetComponent(out SpriteRenderer sr) && enemyComponent != null) { sr.color = Color.red; SendDamage(damage, enemyComponent); } } } } } public void SpecialAttack() { if (!inCooldown && input.controls.SpecialAttackState && canAttack) { Debug.Log("Special Attack Input Recieved"); animator.SetBool("SAttack", true); StartCoroutine(EndSpecialAttackAnimationAfterDelay()); attackCollider.OverlapCollider(new ContactFilter2D(), cols); if (cols.Count > 0) { StartCooldown(); foreach (var col in cols) { EnemyClass enemy = col.transform.root.GetComponentInChildren<EnemyClass>(); if (enemy != null) { enemy.Stun(); SendDamage(damage, enemy); } } } } } public void TakeDamage(int damageAmount) { currentHealth -= damageAmount; animator.SetTrigger("Hurt"); healthBar.SetCurrentHealth(currentHealth); if (currentHealth <= 0) { Die(); } } private void SendDamage(int damageAmount, EnemyClass enemyClass) { enemyClass.TakeDamage(damageAmount); } private void Die() { currentState = CharacterState.Dead; characterMovement.enabled = false; animator.SetTrigger("Dead"); if (lives > 0) { Respawn(); } else { gameOverTransition.GameOver(); } } private void Respawn() { lives -= 1; currentHealth = maxHealth; healthBar.SetMaxHealth(maxHealth); transform.position = FindObjectOfType<RespawnController>().respawnPoint.position; characterMovement.enabled = true; currentState = CharacterState.Idle; } private void StartCooldown() { inCooldown = true; cooldownTimer = cooldownDuration; canAttack = false; } private void EndCooldown() { inCooldown = false; canAttack = true; } private IEnumerator EndAttackAnimationAfterDelay() { yield return new WaitForSeconds(0.5f); animator.SetBool("Attack", false); } private IEnumerator EndSpecialAttackAnimationAfterDelay() { yield return new WaitForSeconds(0.5f); animator.SetBool("SAttack", false); } private void Update() { if (inCooldown) { cooldownTimer -= Time.deltaTime; if (cooldownTimer <= 0) { EndCooldown(); } } if (Mathf.Abs(characterMovement.controls.HorizontalMove) > 0 || Mathf.Abs(characterMovement.controls.VerticalMove) > 0) { currentState = CharacterState.Moving; } else { currentState = CharacterState.Idle; } characterMovement.vSpeed = characterMovement.vSpeed * speedMultiplier; characterMovement.hSpeed = characterMovement.hSpeed * speedMultiplier; } // Collectible interactions public void Food(bool collected) { if (collected) { currentHealth += 10; if (currentHealth > maxHealth) currentHealth = maxHealth; healthBar.SetCurrentHealth(currentHealth); } } public void Star(bool collected) { if (collected) { cooldownDuration -= 1; if (cooldownDuration < ) cooldownDurati } } public void Heart(bool collected) { if (collected) { lives += 1; } } public void SpeedBuff(bool collected) { if (collected) { speedMultiplier += 0.5f; StartCoroutine(ResetSpeedAfterDuration(5f)); } } private IEnumerator ResetSpeedAfterDuration(float duration) { yield return new WaitForSeconds(duration); speedMultiplier -= 0.5f; if (speedMultiplier < 1f) speedMultiplier = 1f; } public void StreetWide(bool collected) { if (collected) { // Implement the specific logic for StreetWide collectible } } public void StopMoving() { characterMovement.vSpeed = 0f; characterMovement.hSpeed = 0f; } } Coin.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using System; //lets me use Action public class Coin : MonoBehaviour, iCollectible//calling on interface { public static event Action OnCoinCollected; //event to change coins public void Collect(){ OnCoinCollected?.Invoke(); Debug.Log("Coin collected!!"); Destroy(gameObject); } } Collector.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public class Collector : MonoBehaviour { private void OnTriggerEnter2D(Collider2D collision){//when touched Debug.Log("Coin Touched"); iCollectible collectible = collision.GetComponent<iCollectible>(); if(collectible != null){//if the icollectiable is found, for any collectible collectible.Collect();//collect it } } } CollectionManager.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; // TextMeshPro public class CollectionManager : MonoBehaviour { private CharacterClass characterClass; public TextMeshProUGUI CoinText; // text public int numCoins = 0; // number of coins collected // add TMPRO and int for each collectible and make a class for it private void Awake() { characterClass = FindObjectOfType<CharacterClass>(); } private void OnEnable() { Coin.OnCoinCollected += CoinCollected; Food.OnFoodCollected += FoodCollected; Star.OnStarCollected += StarCollected; Heart.OnHeartCollected += HeartCollected; Late4Shift.OnSpeedIncrease += SpeedIncrease; // Add event subscriptions for more collectibles } private void OnDisable() { Coin.OnCoinCollected -= CoinCollected; Food.OnFoodCollected -= FoodCollected; Star.OnStarCollected -= StarCollected; Heart.OnHeartCollected -= HeartCollected; Late4Shift.OnSpeedIncrease -= SpeedIncrease; } private void CoinCollected() { numCoins++; CoinText.text = numCoins.ToString(); // converts int to string } private void FoodCollected() { characterClass.Food(true); Debug.Log("Health Sent to Player"); } private void StarCollected() { characterClass.Star(true); Debug.Log("Cooldown Reduction Sent to Player"); } private void HeartCollected() { characterClass.Heart(true); Debug.Log("Health Sent to Player"); } private void SpeedIncrease() { characterClass.SpeedBuff(true); Debug.Log("Speed Boost Sent to Player"); } private void StreetWide() { characterClass.StreetWide(true); Debug.Log("StreetWideWemb sent to player"); } // make new method for when new collectible is added }