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
}