From 9b54472adb70a3b5e4bc8576400a83d93959a8bc Mon Sep 17 00:00:00 2001 From: Andrew Jorgensen Date: Sun, 24 Nov 2024 17:08:39 -0500 Subject: [PATCH] AJ commit --- Assets/MudMan.cs | 233 ---------- Assets/SFX/MudMan.cs | 202 ++++++++ Assets/{ => SFX}/MudMan.cs.meta | 0 Assets/Scripts/Enemy/Boss/Hydra.cs | 252 ++++------ Assets/Scripts/Enemy/Earth/EnemyEarth.cs | 78 +++- Assets/Scripts/Enemy/Ghost/Ghost.cs | 334 ++++---------- Assets/Scripts/GameManager.cs | 130 +++--- Assets/Scripts/Level/BossRoom.cs | 89 ++-- Assets/Scripts/Level/WorldController.cs | 42 +- Assets/Scripts/Player/GameUI.cs | 315 +++++-------- Assets/Scripts/Player/Player.cs | 392 +++++----------- Assets/Scripts/Player/PlayerMovement.cs | 65 +++ Assets/Scripts/Player/PlayerMovement.cs.meta | 11 + Assets/Scripts/Player/Shooter.cs | 456 +++++++------------ Assets/Tutorial.cs | 174 ++++--- 15 files changed, 1171 insertions(+), 1602 deletions(-) delete mode 100644 Assets/MudMan.cs create mode 100644 Assets/SFX/MudMan.cs rename Assets/{ => SFX}/MudMan.cs.meta (100%) create mode 100644 Assets/Scripts/Player/PlayerMovement.cs create mode 100644 Assets/Scripts/Player/PlayerMovement.cs.meta diff --git a/Assets/MudMan.cs b/Assets/MudMan.cs deleted file mode 100644 index a797877..0000000 --- a/Assets/MudMan.cs +++ /dev/null @@ -1,233 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -public class MudMan : MonoBehaviour -{ - public int health; - public GameObject damage; - public GameObject CurrentRoom; - public float cooldown; - private float cooldownCount; - public GameObject Projectile; - public float shotForce = 20f; - - private Vector3 start; - private Vector3 direction; - private GameObject target; - private GameObject target2; - public float sightDistance = 10; - private Collider2D finalDetected; - private RaycastHit hit; - private int layerMask = 1 << 3 | 1 << 7 | 1 << 11 | 1 << 12 | 1 << 13; - - public Vector3 shootAngle; - - public Animator animator; - - - public int heartOrNo; - public GameObject heart; - - public float Horizontal; - public float Vertical; - - private float stupidspeed; - - public GameObject Collider2D; - - // Start is called before the first frame update - void Start() - { - cooldownCount = 0; - target = GameObject.Find("Player"); - target2 = GameObject.Find("Shooter"); - layerMask = ~layerMask; - } - - // Update is called once per frame - void Update() - { - start = this.transform.position; - cooldownCount++; - direction = (target.transform.position - start).normalized; - Debug.DrawRay(start, direction * sightDistance); - - if (SightTest() == target.GetComponent() || SightTest() == target2.GetComponent()) - { - GetComponent().SetActive(true); - animator.Play("MudRise"); - animator.SetBool("Awake", true); - - if (cooldownCount >= cooldown) - { - animator.Play("MudATTACK"); - Shoot(); - - cooldownCount = 0; - } - } - else{ - GetComponent().SetActive(false); - animator.SetBool("Awake", false); - } - finalDetected = null; - shootAngle = (start - target.transform.position).normalized; - shootAngle.y *= -1; - - animator.SetFloat("Horizontal", shootAngle.x); - animator.SetFloat("Vertical", shootAngle.y); - Horizontal = shootAngle.x; - Vertical = shootAngle.y; - - } - - - public void Shoot() - { - //animator.Play("ArcherRightShoot"); - - GameObject arrow = Instantiate(Projectile, start, this.transform.rotation); - - Rigidbody2D rb = arrow.GetComponent(); - if (direction.x < 0) - { - rb.AddForce(direction * shotForce * 15); - } - else - { - rb.AddForce(direction * shotForce * 15); - } - - } - - ///////////////////////////////////////////////////// - ///Sight test - ///////////////////////////////////////////////////// - - public Collider2D SightTest() - { - RaycastHit2D sightTest = Physics2D.Raycast(start, direction, sightDistance, layerMask); - if (sightTest.collider != null) - { - if (sightTest.collider.gameObject != gameObject) - { - finalDetected = null; - //Debug.Log("Rigidbody collider is: " + sightTest.collider); - } - finalDetected = sightTest.collider; - } - return finalDetected; - } - - - /////////////////////////////////////////////// - ///Damage check - /////////////////////////////////////////////// - - public void HurtMe(int damage) - { - health -= damage; - if (health <= 0) - { - int heartOrNo = Random.Range(0,4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if(heartOrNo >= 2) - { - Instantiate (heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } - } - - - public void LightningHurtMe(int ouchie) - { - health -= ouchie - 1; - - if (health <= 0) - { - int heartOrNo = Random.Range(0, 4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } - } - - public void FireHurtMe(int ouchie) - { - health -= ouchie; - - if (health <= 0) - { - int heartOrNo = Random.Range(0, 4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } - } - - public void IceHurtMe(int ouchie) - { - health -= ouchie; - - if (health <= 0) - { - int heartOrNo = Random.Range(0, 4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } - } - - public void EarthHurtMe(int ouchie) - { - health -= ouchie; - - if (health <= 0) - { - int heartOrNo = Random.Range(0, 4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } - } - -} \ No newline at end of file diff --git a/Assets/SFX/MudMan.cs b/Assets/SFX/MudMan.cs new file mode 100644 index 0000000..c43ae44 --- /dev/null +++ b/Assets/SFX/MudMan.cs @@ -0,0 +1,202 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class MudMan : MonoBehaviour +{ + // General settings + public int health; + public GameObject damage; + public GameObject CurrentRoom; + public GameObject Projectile; + public GameObject heart; + + public float cooldown; // Time between attacks + private float cooldownCount; + + // Attack settings + public float shotForce = 20f; + public float sightDistance = 10; + + // Targeting and detection + private Vector3 start; + private Vector3 direction; + private GameObject target; // Main player target + private GameObject target2; // Shooter or secondary target + private Collider2D finalDetected; + private RaycastHit hit; + + private int layerMask = 1 << 3 | 1 << 7 | 1 << 11 | 1 << 12 | 1 << 13; + + // Animator and shooting angles + public Animator animator; + public Vector3 shootAngle; + public float Horizontal; + public float Vertical; + + // Random drop chance + private int heartOrNo; + + // Initialization + void Start() + { + cooldownCount = 0; + target = GameObject.Find("Player"); + target2 = GameObject.Find("Shooter"); + + // Invert layermask for Raycast filtering + layerMask = ~layerMask; + } + + // Update is called once per frame + void Update() + { + start = this.transform.position; // Start position for the enemy + cooldownCount += Time.deltaTime; // Increment cooldown counter + direction = (target.transform.position - start).normalized; // Calculate direction to the target + + Debug.DrawRay(start, direction * sightDistance); // Visualize ray for debugging + + if (SightTest() == target.GetComponent() || SightTest() == target2.GetComponent()) + { + ActivateMudMan(); + + // Attack when cooldown is ready + if (cooldownCount >= cooldown) + { + animator.Play("MudATTACK"); + Shoot(); + cooldownCount = 0; + } + } + else + { + DeactivateMudMan(); + } + + // Reset detection after sight test + finalDetected = null; + + // Calculate shooting angle + shootAngle = (start - target.transform.position).normalized; + shootAngle.y *= -1; + + // Update animator parameters for directional animation + animator.SetFloat("Horizontal", shootAngle.x); + animator.SetFloat("Vertical", shootAngle.y); + Horizontal = shootAngle.x; + Vertical = shootAngle.y; + } + + /// + /// Handles activating MudMan's animations and collider. + /// + private void ActivateMudMan() + { + GetComponent().enabled = true; // Enable collider + animator.Play("MudRise"); + animator.SetBool("Awake", true); + } + + /// + /// Handles deactivating MudMan's animations and collider. + /// + private void DeactivateMudMan() + { + GetComponent().enabled = false; // Disable collider + animator.SetBool("Awake", false); + } + + /// + /// Shoots a projectile at the player. + /// + public void Shoot() + { + GameObject arrow = Instantiate(Projectile, start, this.transform.rotation); + + Rigidbody2D rb = arrow.GetComponent(); + rb.AddForce(direction * shotForce * 15, ForceMode2D.Impulse); // Apply force to the projectile + } + + /// + /// Tests if the MudMan has a clear line of sight to the target. + /// + /// Returns the detected collider. + public Collider2D SightTest() + { + RaycastHit2D sightTest = Physics2D.Raycast(start, direction, sightDistance, layerMask); + + if (sightTest.collider != null && sightTest.collider.gameObject != gameObject) + { + finalDetected = sightTest.collider; + } + + return finalDetected; + } + + /// + /// Damages the MudMan and checks for death. + /// + /// Amount of damage taken. + public void HurtMe(int damage) + { + health -= damage; + CheckDeath(); + } + + /// + /// Damages the MudMan with reduced damage for lightning. + /// + /// Amount of damage taken. + public void LightningHurtMe(int ouchie) + { + health -= ouchie - 1; // Reduced damage for lightning + CheckDeath(); + } + + /// + /// Handles regular fire damage. + /// + public void FireHurtMe(int ouchie) + { + health -= ouchie; + CheckDeath(); + } + + /// + /// Handles regular ice damage. + /// + public void IceHurtMe(int ouchie) + { + health -= ouchie; + CheckDeath(); + } + + /// + /// Handles regular earth damage. + /// + public void EarthHurtMe(int ouchie) + { + health -= ouchie; + CheckDeath(); + } + + /// + /// Checks if MudMan's health is zero or below, and handles destruction and drops. + /// + private void CheckDeath() + { + if (health <= 0) + { + heartOrNo = Random.Range(0, 4); + + if (heartOrNo >= 2) // 50% chance to drop a heart + { + Instantiate(heart, this.transform.position, Quaternion.identity); + } + + Destroy(this.gameObject); // Destroy MudMan + CurrentRoom?.SendMessage("RoomClear"); // Notify room if applicable + } + } +} \ No newline at end of file diff --git a/Assets/MudMan.cs.meta b/Assets/SFX/MudMan.cs.meta similarity index 100% rename from Assets/MudMan.cs.meta rename to Assets/SFX/MudMan.cs.meta diff --git a/Assets/Scripts/Enemy/Boss/Hydra.cs b/Assets/Scripts/Enemy/Boss/Hydra.cs index b4655d2..634e9a3 100644 --- a/Assets/Scripts/Enemy/Boss/Hydra.cs +++ b/Assets/Scripts/Enemy/Boss/Hydra.cs @@ -5,227 +5,177 @@ public class Hydra : MonoBehaviour { public int health; - //public GameObject damage; + public GameObject damage; // Visual effects for damage public GameObject CurrentRoom; - public float cooldown; - private float cooldownCount; - public GameObject[] Projectile; - public Animation[] attack; - public float shotForce = 20f; + public GameObject WIN; // Object to spawn on Hydra defeat + public GameObject[] Projectile; // Array of projectiles for different elements + public Animation[] attack; // Elemental attack animations + public float cooldown; // Time between attacks + public float shotForce = 20f; // Force applied to projectiles + + private float cooldownCount; // Tracks cooldown time + private Vector3 start; // Hydra's position + private Vector3 direction; // Direction to target + private float sightDistance; // Sight toward player + private GameObject target; // Main player target + private GameObject target2; // Secondary target (e.g., Shooter) + private Collider2D finalDetected; // Last detected collider + private int layerMask = 1 << 3; // Layermask for raycasting + private Vector3 shootAngle; // Angle for projectiles + + public Animator animator; // Animator for Hydra animations + public Transform Anchor; // Rotation anchor for projectiles + public Transform EnemyAnchor; + + private bool isSlowed = false; // Tracks if Hydra is affected by ice + private float slowDuration = 3f; // Duration of slow effect + private float slowEffectEndTime = 0f; // Time when slow effect ends - private Vector3 start; - private Vector3 direction; - private GameObject target; - private GameObject target2; - public float sightDistance = 10; - private Collider2D finalDetected; - private RaycastHit hit; - private int layerMask = 1 << 3; - - private Vector3 shootAngle; - - public Animator animator; - - //public Transform anchor; - public GameObject anchor; - - public GameObject WIN; - - private int damage; - - - // Start is called before the first frame update void Start() { cooldownCount = 0; target = GameObject.Find("Player"); target2 = GameObject.Find("Shooter"); - layerMask = ~layerMask; - anchor = GameObject.Find("EnemyAnchor"); - damage = 1; + layerMask = ~layerMask; // Invert layermask for raycast } - // Update is called once per frame void Update() { - start = this.transform.position; - cooldownCount++; - direction = (target.transform.position - start).normalized; - Debug.DrawRay(start, direction * sightDistance); + start = this.transform.position; // Update Hydra's position + cooldownCount += Time.deltaTime; // Increment cooldown timer + direction = (target.transform.position - start).normalized; // Calculate direction to the target + + Debug.DrawRay(start, direction * sightDistance); // Visualize ray for debugging if (SightTest() == target.GetComponent() || SightTest() == target2.GetComponent()) { + // Shoot if cooldown is complete if (cooldownCount >= cooldown) { - Shoot(); cooldownCount = 0; } } - finalDetected = null; - shootAngle = (start - target.transform.position).normalized; - shootAngle.y *= -1; - } - - - public void Shoot() - { - int RandomNum = Random.Range(0,4); - - if(RandomNum == 0) - { - animator.Play("HydraLightningTest"); - } - if(RandomNum == 1) - { - animator.Play("HydraFire"); - } - if(RandomNum == 2) - { - animator.Play("HydraIce"); - } - if(RandomNum == 3) + // Reset slow effect if time has passed + if (isSlowed && Time.time >= slowEffectEndTime) { - animator.Play("HydraEarth"); + ResetSpeed(); } + finalDetected = null; // Reset detection for next frame + } + /// + /// Shoots a random elemental projectile. + /// + public void Shoot() + { + int RandomNum = Random.Range(0, 4); // Randomize attack type + + // Play corresponding attack animation + switch (RandomNum) + { + case 0: + animator.Play("HydraLightning"); + break; + case 1: + animator.Play("HydraFire"); + break; + case 2: + animator.Play("HydraIce"); + break; + case 3: + animator.Play("HydraEarth"); + break; + } + + // Instantiate and fire projectile GameObject arrow = Instantiate(Projectile[RandomNum], start, this.transform.rotation); - - arrow.transform.rotation = anchor.transform.rotation; - print("Hydra firing at " + direction); + arrow.transform.rotation = Anchor.transform.rotation; Rigidbody2D rb = arrow.GetComponent(); - if (direction.x < 0) - { - rb.AddForce(direction * shotForce * 25); - } - else - { - rb.AddForce(direction * shotForce * 15); - } - + rb.AddForce(direction * shotForce, ForceMode2D.Impulse); } - - + /// + /// Tests if the Hydra has a clear line of sight to the target. + /// public Collider2D SightTest() { RaycastHit2D sightTest = Physics2D.Raycast(start, direction, sightDistance, layerMask); - if (sightTest.collider != null) + + if (sightTest.collider != null && sightTest.collider.gameObject != gameObject) { - if (sightTest.collider.gameObject != gameObject) - { - finalDetected = null; - //Debug.Log("Rigidbody collider is: " + sightTest.collider); - } finalDetected = sightTest.collider; } + return finalDetected; } - - - - + /// + /// Handles collisions with magic projectiles. + /// public void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.CompareTag("Fire") || other.gameObject.CompareTag("BigFire")) { Destroy(other.gameObject); - - //damage = 1; - //HurtMe(); - //GameObject explo = Instantiate(damage, this.transform.position, Quaternion.identity); - //Destroy(explo, 1f); - - + TakeDamage(2); // Fire damage } - if (other.gameObject.CompareTag("Earth")) + else if (other.gameObject.CompareTag("Earth")) { - Destroy(other.gameObject); - //damage = 3; - //HurtMe(); - + TakeDamage(3); // Earth damage } - if (other.gameObject.CompareTag("Lightning")) + else if (other.gameObject.CompareTag("Lightning") || other.gameObject.CompareTag("BigLightning")) { Destroy(other.gameObject); - //damage = 1; - //HurtMe(); + TakeDamage(1); // Lightning damage } - if (other.gameObject.CompareTag("BigLightning")) + else if (other.gameObject.CompareTag("Ice")) { - //Destroy(other.gameObject); - //damage = 3; - //HurtMe(); + Destroy(other.gameObject); + TakeDamage(1); // Ice damage + IceSlowEffect(); // Apply ice slow effect } } - - /////////////////////////////////////////////// - ///Damage check - /////////////////////////////////////////////// - public void HurtMe(int damage) + /// + /// Reduces Hydra's health and checks for death. + /// + public void TakeDamage(int damage) { health -= damage; - if (health <= 0) - { - Instantiate(WIN, this.transform.position, Quaternion.identity); - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } - } - - - public void LightningHurtMe(int ouchie) - { - health -= ouchie; if (health <= 0) { Instantiate(WIN, this.transform.position, Quaternion.identity); - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); + Destroy(this.gameObject); // Destroy Hydra on death + CurrentRoom?.SendMessage("RoomClear"); // Notify the room manager } } - public void FireHurtMe(int ouchie) + /// + /// Applies a slow effect when hit by ice magic. + /// + public void IceSlowEffect() { - health -= ouchie; - - if (health <= 0) + if (!isSlowed) // Only apply slow if not already slowed { - Instantiate(WIN, this.transform.position, Quaternion.identity); - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); + isSlowed = true; + cooldown *= 1.5f; // Increase cooldown time (slow attack rate) } - } - public void IceHurtMe(int ouchie) - { - health -= ouchie; - - if (health <= 0) - { - Instantiate(WIN, this.transform.position, Quaternion.identity); - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } + slowEffectEndTime = Time.time + slowDuration; // Set time to end slow effect } - public void EarthHurtMe(int ouchie) + /// + /// Resets Hydra's speed after slow effect ends. + /// + public void ResetSpeed() { - health -= ouchie; - - if (health <= 0) - { - Instantiate(WIN, this.transform.position, Quaternion.identity); - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } + isSlowed = false; + cooldown /= 1.5f; // Restore original cooldown } - } \ No newline at end of file diff --git a/Assets/Scripts/Enemy/Earth/EnemyEarth.cs b/Assets/Scripts/Enemy/Earth/EnemyEarth.cs index 07c230e..a0cda72 100644 --- a/Assets/Scripts/Enemy/Earth/EnemyEarth.cs +++ b/Assets/Scripts/Enemy/Earth/EnemyEarth.cs @@ -4,51 +4,85 @@ public class EnemyEarth : MonoBehaviour { - float shootSpeed = 100f; - GameObject Pummel; - GameObject iceshatter; - GameObject fire; - GameObject zappy; + [SerializeField] private float shootSpeed = 100f; // Adjustable in Inspector + [SerializeField] private GameObject pummelPrefab; // Assign prefab in Inspector + [SerializeField] private GameObject iceShatterPrefab; // Assign prefab in Inspector + [SerializeField] private GameObject firePrefab; // Assign prefab in Inspector + [SerializeField] private GameObject zappyPrefab; // Assign prefab in Inspector + [SerializeField] private float selfDestructTime = 0.4f; // How long before the object destroys itself + + private Rigidbody2D r2d; void Start() { - Rigidbody2D r2d = this.GetComponent(); - r2d.AddForce(new Vector2(shootSpeed,10f)); - //GetComponent().Play(); - Destroy(this.gameObject, .4f); + r2d = GetComponent(); + + // Apply a force to the object + Vector2 shootDirection = new Vector2(1, 0.1f).normalized; // Direction with slight upward angle + r2d.AddForce(shootDirection * shootSpeed); + + // Destroy the object after a set amount of time + Destroy(this.gameObject, selfDestructTime); } - public void OnTriggerEnter2D (Collider2D other) + public void OnTriggerEnter2D(Collider2D other) { + // Check for collision with Player if (other.gameObject.CompareTag("Player")) { - other.gameObject.SendMessage("HurtMe", 2); + Player player = other.gameObject.GetComponent(); + if (player != null) + { + player.HurtMe(2); // Call the HurtMe method directly + } } + // Check for collision with Fire if (other.gameObject.CompareTag("Fire")) { - Destroy(other.gameObject); - GameObject fire = Instantiate(fire, this.transform.position, Quaternion.identity); + Destroy(other.gameObject); // Destroy the fire object + if (firePrefab != null) + { + InstantiateEffect(firePrefab); // Create fire explosion + } } + // Check for collision with Lightning if (other.gameObject.CompareTag("Lightning")) { - Destroy(other.gameObject); - GameObject zap = Instantiate(zappy, this.transform.position, Quaternion.identity); + Destroy(other.gameObject); // Destroy the lightning object + if (zappyPrefab != null) + { + InstantiateEffect(zappyPrefab); // Create lightning effect + } } + // Check for collision with Ice if (other.gameObject.CompareTag("Ice")) { - Destroy(other.gameObject); - GameObject ice = Instantiate(iceshatter, this.transform.position, Quaternion.identity); + Destroy(other.gameObject); // Destroy the ice object + if (iceShatterPrefab != null) + { + InstantiateEffect(iceShatterPrefab); // Create ice shatter effect + } } - + // Check for collision with Earth or other large objects if (other.gameObject.CompareTag("Earth") || other.gameObject.CompareTag("BigFire") || other.gameObject.CompareTag("BigLightning")) { - print("boom"); - GameObject explo = Instantiate(Pummel, this.transform.position, Quaternion.identity); - Destroy(this.gameObject); + Debug.Log("Boom!"); // Log the collision + if (pummelPrefab != null) + { + InstantiateEffect(pummelPrefab); // Create explosion effect + } + Destroy(this.gameObject); // Destroy this object } } -} + + // Helper method to instantiate effects and clean up afterward + private void InstantiateEffect(GameObject effectPrefab) + { + GameObject effect = Instantiate(effectPrefab, transform.position, Quaternion.identity); + Destroy(effect, 1f); // Destroy the effect after 1 second (adjust as needed) + } +} \ No newline at end of file diff --git a/Assets/Scripts/Enemy/Ghost/Ghost.cs b/Assets/Scripts/Enemy/Ghost/Ghost.cs index de21569..ab4f728 100644 --- a/Assets/Scripts/Enemy/Ghost/Ghost.cs +++ b/Assets/Scripts/Enemy/Ghost/Ghost.cs @@ -2,291 +2,133 @@ using System.Collections.Generic; using UnityEngine; -public class Ghost: MonoBehaviour +public class Ghost : MonoBehaviour { - GameObject damage; - GameObject currentRoom; - Animator animator; - Transform aim; - Transform aimTarget; - Vector2 AwareOfPlayer; - Vector2 DirectionToPlayer; - GameObject Heart; - GameObject playertarget; - GameObject PlayerUI; - GameObject Getplayertarget; - Transform Player; - [SerializeField] - float speed; - [SerializeField] + [SerializeField] private GameObject damagePrefab; // Assign in the Inspector + [SerializeField] private GameObject heartPrefab; // Prefab for the heart + [SerializeField] private Transform anchor; + [SerializeField] private float speed = 4f; + [SerializeField] private float playerAwarenessDistance = 5f; // Awareness range + [SerializeField] private int health = 10; - readonly Transform aim1; + private Transform player; // Cached reference to the player + private bool awareOfPlayer = false; + private Vector2 directionToPlayer; + private Animator animator; + private Rigidbody2D rb; - GameObject GetPlayerTarget() => ghost.playertarget; + public GameObject playertarget; // Assigned in Start - void SetPlayertarget(GameObject target) => aimTarget = target; - - //float rotationSpeed = 100; - //PlayerAware ThisPlayerAware; - Vector2 targetdirection; - public GameObject sprite; - public GameObject anchor; - // Start is called before the first frame update void Start() { - //////////////////////////////////////// - ///PlayerAware Code - //////////////////////////////////////// - playertarget = GameObject.Find("Aim"); - //print(playertarget); - player = playertarget.transform; + // Cache components + animator = GetComponent(); + rb = GetComponent(); - ///////////////////////////////////////// - ///GhostMovement Code - ///////////////////////////////////////// - ///print("awake"); - Player = GameObject.Find("Player"); - player = Player.transform; - anchor = GameObject.Find("EnemyAnchor"); - playerAwarenessDistance = GetComponent(); - //ThisPlayerAware = GetComponent(); - speed = 4f; + // Find references (can be assigned through the Inspector instead for better performance) + playertarget = GameObject.Find("Aim"); + player = GameObject.Find("Player")?.transform; + anchor = GameObject.Find("EnemyAnchor")?.transform; } - // Update is called once per frame void Update() { - Vector2 enemyToPlayerVector = player.position - transform.position; - DirectionToPlayer = enemyToPlayerVector; + if (player == null) return; - //print(enemyToPlayerVector); - //print(enemyToPlayerVector.magnitude); + // Calculate direction to the player + Vector2 enemyToPlayerVector = player.position - transform.position; + directionToPlayer = enemyToPlayerVector; -if (enemyToPlayerVector.magnitude <= playerAwarenessDistance) -{ - //print("Found player"); - AwareOfPlayer = true; -} -else -{ - //print("Lost player"); - AwareOfPlayer = false; -} + // Check if player is within awareness distance + awareOfPlayer = enemyToPlayerVector.magnitude <= playerAwarenessDistance; } - void DamageGhost(int damage) + + void FixedUpdate() { - // Reduce the ghost's health - health.GetComponent().TakeDamage(damage); - /////////////////////////////////////////////// - ///Damage check - /////////////////////////////////////////////// - void HurtMe(int damage) + if (awareOfPlayer) { - health -= damage; - if (health <= 0) - { - int heartOrNo = Random.Range(0, 4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } + RotateTowardsTarget(); + MoveTowardsPlayer(); } - - - void LightningHurtMe(int ouchie) + else { - health -= ouchie + 1; - - if (health <= 0) - { - int heartOrNo = Random.Range(0, 4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } + rb.velocity = Vector2.zero; // Stop movement if unaware } + } - void FireHurtMe(int ouchie) - { - health -= ouchie; - - if (health <= 0) - { - int heartOrNo = Random.Range(0, 4); + private void RotateTowardsTarget() + { + Vector2 direction = directionToPlayer.normalized; + float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg; + rb.rotation = angle; // Rotate the Rigidbody + } - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); + private void MoveTowardsPlayer() + { + rb.velocity = directionToPlayer.normalized * speed; // Move the Rigidbody + } - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } + // Damage the ghost + public void DamageGhost(int damage) + { + health -= damage; - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } + if (health <= 0) + { + DropHeart(); + Destroy(gameObject); + SendRoomClearMessage(); } + } - void IceHurtMe(int ouchie) + private void DropHeart() + { + int heartOrNo = Random.Range(0, 4); + if (heartOrNo >= 2 && heartPrefab != null) { - health -= ouchie; - - if (health <= 0) - { - int heartOrNo = Random.Range(0, 4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); - } + Instantiate(heartPrefab, transform.position, Quaternion.identity); } + } + + private void SendRoomClearMessage() + { + GameObject currentRoom = GameObject.Find("CurrentRoom"); + currentRoom?.SendMessage("RoomClear"); + } - void EarthHurtMe(int ouchie) + private void OnTriggerEnter2D(Collider2D other) + { + if (other.gameObject.CompareTag("Fire")) { + Destroy(other.gameObject); + DamageGhost(1); - if (health <= 0) + if (damagePrefab != null) { - int heartOrNo = Random.Range(0, 4); - - print(heartOrNo); - //Instantiate (heart, this.transform.position, Quaternion.identity); - - if (heartOrNo >= 2) - { - Instantiate(heart, this.transform.position, Quaternion.identity); - } - - Destroy(this.gameObject); - CurrentRoom.gameObject.SendMessage("RoomClear"); + GameObject explosion = Instantiate(damagePrefab, transform.position, Quaternion.identity); + Destroy(explosion, 1f); } } - - void OnTriggerEnter2D( Collider2D other) - { - -if(other.gameObject.CompareTag("Fire")) -{ - Destroy(other.gameObject); - HurtMe(1); - GameObject explo = Instantiate(damage, this.transform.position, Quaternion.identity); - Destroy(explo, 1f); - - -} -if(other.gameObject.CompareTag("FILLERTEXT")) -{ - -if(health <= 0) -{ - Destroy(this.gameObject); -} -} -if(other.gameObject.CompareTag("Earth")) -{ - -} -if(other.gameObject.CompareTag("Lightning")) -{ - Destroy(other.gameObject); -} -if(other.gameObject.CompareTag("Ice")) -{ - Destroy(other.gameObject); -} - -if(other.gameObject.CompareTag("Player")) -{ - - -animator.Play("GoopAttack"); - -//other.gameObject.SendMessage("EnemyCollide"); - - -} - } - - void FixedUpdate() + else if (other.gameObject.CompareTag("Lightning")) { - UpdateTargetDirection(); - RotateTowardsTarget(); - SetVelocity(); - sprite.transform.rotation = anchor.transform.rotation; - + Destroy(other.gameObject); + DamageGhost(2); } - - void UpdateTargetDirection() + else if (other.gameObject.CompareTag("Ice")) { - //print("UpdateTargetDirection"); - if (AwareOfPlayer) - { - targetdirection = DirectionToPlayer; - } - else - { - targetdirection = Vector2.zero; - } - //print("target direction = " + targetdirection); - + Destroy(other.gameObject); + DamageGhost(1); } - - void RotateTowardsTarget() + else if (other.gameObject.CompareTag("Player")) { - //print("RotateTowardsTarget"); - if (targetdirection == Vector2.zero) - { - //print("targetdirection == Vector2.zero"); - return; - } - - // Quaternion targetRotation = Quaternion.LookRotation(transform.foward, targetdirection); - //Quaternion rotation = Quaternion.RotateTowards(player.transform.rotation, targetdirection, rotationSpeed* Time.deltaTime); - //rigidbody.transform.rotation = player.transform.rotation; - GetComponent().transform.rotation = sprite.transform.rotation; + animator.Play("GoopAttack"); + // Handle player collision } + } - void SetVelocity() - { - //print("SetVelocity"); - if (targetdirection == Vector2.zero) - { - //print("no direction"); - this.GetComponent().velocity = Vector2.zero; - - } - else - { - this.GetComponent().velocity = transform.up * speed; - //this.GetComponent().AddForce(transform.up * speed); - //print("transform.up = " + this.transform.up); - //print("transform.up = " + transform.up); - //print("speed = " + speed); - // print("velocity = " + this.GetComponent().velocity); - //print("velocity should be = " + transform.up * speed); - } - } + // Method to get the player target + public GameObject GetPlayerTarget() + { + return playertarget; } } \ No newline at end of file diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index ab34e6e..3c631ea 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -1,53 +1,58 @@ using System.Collections; -using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { + [Header("Room Settings")] + public int roomCount = 0; // Tracks the number of rooms + public GameObject currentPlacer; // Reference to the current placer object + public string combination; // String to locate room placers + public Vector3 offsetTotal; // Tracks the cumulative offset for room placement + private bool needsOffset; // Flag to determine if an offset is required + private int whichOffset; // Specifies which offset to apply - public int roomCount; - public GameObject currentPlacer; - public string combination; - //public Vector3[] Offsets; - public Vector3 offsetTotal; - private bool needsOffset; - private int whichOffset; + [Header("Room Offsets")] + public Vector3 lightningLevel1 = new Vector3(0f, 18.17f, 0f); // Example offset for Lightning Level 1 - - //offsets declared here because unity is stupid - //public Vector3 lightningLevel1 = new Vector3(0f, 18.17f, 0f); - //public Vector3 lightningLevel1 = new Vector3(0f, 9.55f, 0f); - public Vector3 lightningLevel1; - - // Start is called before the first frame update void Start() { - roomCount = 0; + GenerateRooms(); + } - for(int i = 1; i < 7; i++) + /// + /// Generates rooms based on random logic. + /// + private void GenerateRooms() + { + for (int i = 1; i <= 6; i++) { - combination = "Placer (" + i + ")"; + // Find the current room placer + combination = $"Placer ({i})"; currentPlacer = GameObject.Find(combination); - print("Current Placer = " + currentPlacer); - //print("Combination = " + combination); - int RandomRoom = Random.Range(0, 6); - print("Random Room = " + RandomRoom); - if(RandomRoom == 5) + + if (currentPlacer == null) + { + Debug.LogWarning($"Placer object '{combination}' not found!"); + continue; + } + + // Determine the random room type + int randomRoom = Random.Range(0, 6); + Debug.Log($"Placer {i}: Random Room = {randomRoom}"); + + // If the room requires an offset + if (randomRoom == 5) { needsOffset = true; whichOffset = 1; - print("Random Room = 5 Bool is true"); - print("Lightning level offset = " + lightningLevel1); - //currentPlacer.SendMessage("GetOffset", offsetTotal); - print("Offset total = " + offsetTotal); - + Debug.Log($"Room {i} needs offset. Offset: {lightningLevel1}"); } + + // Create a normal room or boss room if (i < 6) { - //currentPlacer.SendMessage("GetOffset", offsetTotal); currentPlacer.SendMessage("SetPosition", offsetTotal); - currentPlacer.SendMessage("CreateRoom", RandomRoom); - + currentPlacer.SendMessage("CreateRoom", randomRoom); } else { @@ -55,46 +60,55 @@ void Start() currentPlacer.SendMessage("CreateBossRoom", SendMessageOptions.DontRequireReceiver); } + // Apply the offset if required if (needsOffset) { - switch (whichOffset) - { - case 1: - offsetTotal += lightningLevel1; - needsOffset = false; - whichOffset = 0; - break; - } - - } + ApplyOffset(); } - - - + } } - // Update is called once per frame - void Update() + /// + /// Applies the required offset based on the current offset type. + /// + private void ApplyOffset() { - //print("Game Manager Room Count is " + roomCount); + switch (whichOffset) + { + case 1: + offsetTotal += lightningLevel1; + break; + default: + Debug.LogWarning("Unknown offset type. No offset applied."); + break; + } + + needsOffset = false; // Reset the flag + whichOffset = 0; // Reset the offset type } + /// + /// Increments the room count. + /// public void IncreaseRoomCount() { roomCount++; - //print("Room count increased to " + roomCount); - + Debug.Log($"Room count increased to {roomCount}"); } - + /// + /// Sends the current room count to the specified GameObject. + /// public void SendRoomCount(GameObject other) { - //print("Recieved room count from " + other); - //print("Sending roomcount " + roomCount + " to " + other); - other.SendMessage("GetRoomCount", roomCount); + if (other != null) + { + Debug.Log($"Sending room count {roomCount} to {other.name}"); + other.SendMessage("GetRoomCount", roomCount, SendMessageOptions.DontRequireReceiver); + } + else + { + Debug.LogWarning("SendRoomCount called with a null GameObject."); + } } - - - - -} +} \ No newline at end of file diff --git a/Assets/Scripts/Level/BossRoom.cs b/Assets/Scripts/Level/BossRoom.cs index 453832b..75d7219 100644 --- a/Assets/Scripts/Level/BossRoom.cs +++ b/Assets/Scripts/Level/BossRoom.cs @@ -4,51 +4,78 @@ public class BossRoom : MonoBehaviour { + [SerializeField] private GameObject entrance; // Assign in the Inspector + [SerializeField] private GameObject exit; // Assign in the Inspector + [SerializeField] private GameObject[] enemies; // Assign in the Inspector or populate dynamically + [SerializeField] private GameObject player; // Assign in the Inspector - int enemies; - GameObject Entrance; - GameObject Exit; - int count; - int countdown; - GameObject[] Enemies; - GameObject player; - int enter; + private bool roomLocked = false; // Tracks whether the room is locked + private int remainingEnemies; void Start() { - Entrance.gameObject.SetActive(false); - Exit.gameObject.SetActive(false); - enter= 0; - player = GameObject.Find("Player"); + if (entrance != null) entrance.SetActive(false); + if (exit != null) exit.SetActive(false); + + // If enemies are not assigned manually, find them dynamically + if (enemies == null || enemies.Length == 0) + { + enemies = GameObject.FindGameObjectsWithTag("Enemy"); + } + + // Set the initial count of enemies + remainingEnemies = enemies.Length; + + // Deactivate all enemies initially + foreach (GameObject enemy in enemies) + { + enemy.SetActive(false); + } + + if (player == null) + { + player = GameObject.Find("Player"); // Find player dynamically if not assigned + } } - void Update() - { - void RoomLock() + private void OnTriggerEnter2D(Collider2D other) { - if(enter < 1) + if (!roomLocked && other.gameObject == player) { - Entrance.gameObject.SetActive(true); - Exit.gameObject.SetActive(true); - enter = enter+1; + RoomLock(); + } + } - for(int i = 0; i < Enemies.Length; i++) - { - Enemies[i].SetActive(true); - } + private void RoomLock() + { + roomLocked = true; - player.SendMessage("StartBossMusic", SendMessageOptions.DontRequireReceiver); + if (entrance != null) entrance.SetActive(true); + if (exit != null) exit.SetActive(true); + + // Activate all enemies + foreach (GameObject enemy in enemies) + { + enemy.SetActive(true); } + + // Notify the player to start the boss music (if implemented in the player's script) + if (player != null) + { + player.SendMessage("StartBossMusic", SendMessageOptions.DontRequireReceiver); } } - void RoomClear() + + public void RoomClear() { - //print ("enemy down"); - enemies= enemies-1; - if(enemies<=0) + remainingEnemies--; + + if (remainingEnemies <= 0) { - Entrance.gameObject.SetActive(false); - Exit.gameObject.SetActive(false); + if (entrance != null) entrance.SetActive(false); + if (exit != null) exit.SetActive(false); + + Debug.Log("Boss room cleared!"); } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Level/WorldController.cs b/Assets/Scripts/Level/WorldController.cs index 4d5819c..66ac721 100644 --- a/Assets/Scripts/Level/WorldController.cs +++ b/Assets/Scripts/Level/WorldController.cs @@ -1,34 +1,46 @@ using System.Collections; -using System.Collections.Generic; using UnityEngine; public class WorldController : MonoBehaviour { - public GameObject destroy; - public GameObject player; - // Start is called before the first frame update - void Start() + [Header("References")] + public GameObject destroy; // Object to destroy + public GameObject player; // Reference to the player + + [Header("Input Settings")] + public string destroyInput = "Fire1"; // Input to destroy the object + public string damageInput = "Ouch"; // Input to simulate damage to the player + public string winInput = "Win"; // Input to trigger a win state + + void Update() { - + HandleInputs(); } - // Update is called once per frame - void Update() + /// + /// Processes user inputs and triggers corresponding actions. + /// + private void HandleInputs() { - if( Input.GetButtonDown("Fire1")) + // Destroy object when the specified input is pressed + if (Input.GetButtonDown(destroyInput) && destroy != null) { Destroy(destroy); + Debug.Log($"Destroyed object: {destroy.name}"); } - if( Input.GetButtonDown("Ouch")) + // Simulate player taking damage + if (Input.GetButtonDown(damageInput) && player != null) { - player.gameObject.SendMessage("EnemyCollide"); + player.SendMessage("EnemyCollide", SendMessageOptions.DontRequireReceiver); + Debug.Log("Triggered EnemyCollide on the player."); } - if( Input.GetButtonDown("Win")) + // Trigger a win state + if (Input.GetButtonDown(winInput) && player != null) { - player.gameObject.SendMessage("Win"); + player.SendMessage("Win", SendMessageOptions.DontRequireReceiver); + Debug.Log("Triggered Win on the player."); } - } -} +} \ No newline at end of file diff --git a/Assets/Scripts/Player/GameUI.cs b/Assets/Scripts/Player/GameUI.cs index ff2268a..701c2f8 100644 --- a/Assets/Scripts/Player/GameUI.cs +++ b/Assets/Scripts/Player/GameUI.cs @@ -1,247 +1,164 @@ using System.Collections; -using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class GameUI : MonoBehaviour { - int health; - - GameObject health1of5; - GameObject health2of5; - GameObject health3of5; - GameObject health4of5; - GameObject health5of5; - - Image Lightning; - Image Fire; - Image Ice; - Image Earth; - Image lightningSelect; - Image fireSelect; - Image iceSelect; - Image earthSelect; - - float iceCooldown; - float fireCooldown; - float earthCooldown; - float lightningCooldown; - - float iceTime; - float fireTime; - float earthTime; - float lightningTime; - - bool iceSent; - bool fireSent; - bool earthSent; - bool lightningSent; - - GameObject Shooter; - bool BossStart = true; - - // Start is called before the first frame update + [Header("Health Display")] + public GameObject[] healthIcons; // Array to hold health UI icons + + [Header("Element Selection")] + public Image Lightning, Fire, Ice, Earth; // Cooldown progress images + public GameObject lightningSelect, fireSelect, iceSelect, earthSelect; // Element selectors + + [Header("Cooldown Timers")] + private float iceCooldown, fireCooldown, earthCooldown, lightningCooldown; + private float iceTime, fireTime, earthTime, lightningTime; + private bool iceSent, fireSent, earthSent, lightningSent; + + [Header("Shooter Reference")] + public GameObject Shooter; + + private int health = 5; // Initial health + private bool bossStart = true; // Tracks boss initialization + void Start() { - lightningSelect.gameObject.SetActive(true); - fireSelect.gameObject.SetActive(false); - iceSelect.gameObject.SetActive(false); - earthSelect.gameObject.SetActive(false); - - Shooter = GameObject.Find("Shooter"); + // Initialize element selection + lightningSelect.SetActive(true); + fireSelect.SetActive(false); + iceSelect.SetActive(false); + earthSelect.SetActive(false); + + // Find Shooter GameObject if not assigned + if (Shooter == null) + Shooter = GameObject.Find("Shooter"); } - // Update is called once per frame void Update() { - if(health == 5) - { - //print("Health 5, = " + health); - health1of5.gameObject.SetActive(true); - health2of5.gameObject.SetActive(true); - health3of5.gameObject.SetActive(true); - health4of5.gameObject.SetActive(true); - health5of5.gameObject.SetActive(true); - } - if(health == 4) - { - //print("Health 4, = " + health); - health1of5.gameObject.SetActive(false); - health2of5.gameObject.SetActive(true); - health3of5.gameObject.SetActive(true); - health4of5.gameObject.SetActive(true); - health5of5.gameObject.SetActive(true); - } - if(health == 3) - { - //print("Health 3, = " + health); - health1of5.gameObject.SetActive(false); - health2of5.gameObject.SetActive(false); - health3of5.gameObject.SetActive(true); - health4of5.gameObject.SetActive(true); - health5of5.gameObject.SetActive(true); - } - if(health == 2) - { - //print("Health 2, = " + health); + UpdateHealthDisplay(); + HandleCooldowns(); + InitializeBossState(); + } - health1of5.gameObject.SetActive(false); - health2of5.gameObject.SetActive(false); - health3of5.gameObject.SetActive(false); - health4of5.gameObject.SetActive(true); - health5of5.gameObject.SetActive(true); - } - if(health == 1) + /// + /// Updates the health display based on the current health value. + /// + private void UpdateHealthDisplay() + { + for (int i = 0; i < healthIcons.Length; i++) { - // print("Health 1, = " + health); - - health1of5.gameObject.SetActive(false); - health2of5.gameObject.SetActive(false); - health3of5.gameObject.SetActive(false); - health4of5.gameObject.SetActive(false); - health5of5.gameObject.SetActive(true); + healthIcons[i].SetActive(i < health); } - if(health <= 0) - { - //print("Health 0, = " + health); + } - health1of5.gameObject.SetActive(false); - health2of5.gameObject.SetActive(false); - health3of5.gameObject.SetActive(false); - health4of5.gameObject.SetActive(false); - health5of5.gameObject.SetActive(false); - } + /// + /// Handles the cooldown logic for all elements. + /// + private void HandleCooldowns() + { + HandleCooldown(ref iceTime, iceCooldown, Ice, "IceEnable", ref iceSent); + HandleCooldown(ref fireTime, fireCooldown, Fire, "FireEnable", ref fireSent); + HandleCooldown(ref earthTime, earthCooldown, Earth, "EarthEnable", ref earthSent); + HandleCooldown(ref lightningTime, lightningCooldown, Lightning, "LightningEnable", ref lightningSent); + } - if(iceTime < iceCooldown) - { - iceSent = false; - //print(iceTime / iceCooldown); - Ice.fillAmount = (iceTime / iceCooldown); - iceTime += Time.deltaTime; - } - else if(iceTime > iceCooldown && iceSent == false) - { - Ice.fillAmount = 1; - iceSent = true; - Shooter.SendMessage("IceEnable", SendMessageOptions.DontRequireReceiver); - } - if(fireTime < fireCooldown) - { - fireSent = false; - //print(fireTime / fireCooldown); - Fire.fillAmount = (fireTime / fireCooldown); - fireTime += Time.deltaTime; - } - else if(fireTime > fireCooldown && fireSent == false) - { - Fire.fillAmount = 1; - fireSent = true; - Shooter.SendMessage("FireEnable", SendMessageOptions.DontRequireReceiver); - } - if(earthTime < earthCooldown +.01f) - { - earthSent = false; - //print(earthTime / earthCooldown); - Earth.fillAmount = (earthTime / earthCooldown); - earthTime += Time.deltaTime; - } - else if(earthTime > earthCooldown +.01f && earthSent == false) - { - Earth.fillAmount = 1; - earthSent = true; - Shooter.SendMessage("EarthEnable", SendMessageOptions.DontRequireReceiver); - } - if (lightningTime < lightningCooldown) + /// + /// Handles cooldown for a specific element. + /// + private void HandleCooldown(ref float currentTime, float cooldown, Image elementImage, string enableMethod, ref bool sent) + { + if (currentTime < cooldown) { - lightningSent = false; - //print(iceTime / iceCooldown); - Lightning.fillAmount = (lightningTime / lightningCooldown); - lightningTime += Time.deltaTime; + sent = false; + elementImage.fillAmount = currentTime / cooldown; + currentTime += Time.deltaTime; } - else if (lightningTime > lightningCooldown && lightningSent == false) + else if (!sent) { - Lightning.fillAmount = 1; - lightningSent = true; - Shooter.SendMessage("LightningEnable", SendMessageOptions.DontRequireReceiver); + elementImage.fillAmount = 1; + sent = true; + Shooter.SendMessage(enableMethod, SendMessageOptions.DontRequireReceiver); } + } + /// + /// Initializes the boss state and prepares all elements. + /// + private void InitializeBossState() + { + if (!bossStart) return; + Shooter.SendMessage("LightningReady", SendMessageOptions.DontRequireReceiver); + Shooter.SendMessage("EarthReady", SendMessageOptions.DontRequireReceiver); + Shooter.SendMessage("FireReady", SendMessageOptions.DontRequireReceiver); + Shooter.SendMessage("IceReady", SendMessageOptions.DontRequireReceiver); - if (BossStart) - { - Shooter.SendMessage("LightningReady", SendMessageOptions.DontRequireReceiver); - Shooter.SendMessage("EarthReady", SendMessageOptions.DontRequireReceiver); - Shooter.SendMessage("FireReady", SendMessageOptions.DontRequireReceiver); - Shooter.SendMessage("IceReady", SendMessageOptions.DontRequireReceiver); - BossStart = false; - } - - + bossStart = false; } + /// + /// Activates the currently selected element UI. + /// + /// Index of the active element (1 = Lightning, 2 = Fire, 3 = Ice, 4 = Earth). void ActiveElement(int index) { - if(index == 1) - { - lightningSelect.gameObject.SetActive(true); - fireSelect.gameObject.SetActive(false); - iceSelect.gameObject.SetActive(false); - earthSelect.gameObject.SetActive(false); - } - else if(index == 2) - { - fireSelect.gameObject.SetActive(true); - lightningSelect.gameObject.SetActive(false); - iceSelect.gameObject.SetActive(false); - earthSelect.gameObject.SetActive(false); - } - else if(index == 3) - { - iceSelect.gameObject.SetActive(true); - lightningSelect.gameObject.SetActive(false); - fireSelect.gameObject.SetActive(false); - earthSelect.gameObject.SetActive(false); - } - else if(index == 4) - { - earthSelect.gameObject.SetActive(true); - lightningSelect.gameObject.SetActive(false); - fireSelect.gameObject.SetActive(false); - iceSelect.gameObject.SetActive(false); - } + lightningSelect.SetActive(index == 1); + fireSelect.SetActive(index == 2); + iceSelect.SetActive(index == 3); + earthSelect.SetActive(index == 4); } + /// + /// Reduces health by the specified damage amount. + /// void Hurt(int damage) { - print("taking damage"); - health -= damage; + health = Mathf.Max(health - damage, 0); // Ensure health doesn't drop below 0 } - void Health() + + /// + /// Increases health by 1. + /// + void Heal() { - health = health + 1; + health = Mathf.Min(health + 1, healthIcons.Length); // Ensure health doesn't exceed max health } - + + /// + /// Sets the cooldown for Ice and starts tracking. + /// void IceCooldown(float cooldown) { - iceCooldown = Time.deltaTime + cooldown; - iceTime = Time.deltaTime; + iceCooldown = cooldown; + iceTime = 0f; } - + + /// + /// Sets the cooldown for Fire and starts tracking. + /// void FireCooldown(float cooldown) { - fireCooldown = Time.deltaTime + cooldown; - fireTime = Time.deltaTime; + fireCooldown = cooldown; + fireTime = 0f; } - + + /// + /// Sets the cooldown for Earth and starts tracking. + /// void EarthCooldown(float cooldown) { - earthCooldown = Time.deltaTime + cooldown; - earthTime = Time.deltaTime; + earthCooldown = cooldown; + earthTime = 0f; } - + + /// + /// Sets the cooldown for Lightning and starts tracking. + /// void LightningCooldown(float cooldown) { - lightningCooldown = Time.deltaTime + cooldown; - lightningTime = Time.deltaTime; + lightningCooldown = cooldown; + lightningTime = 0f; } } \ No newline at end of file diff --git a/Assets/Scripts/Player/Player.cs b/Assets/Scripts/Player/Player.cs index 896244c..f37824e 100644 --- a/Assets/Scripts/Player/Player.cs +++ b/Assets/Scripts/Player/Player.cs @@ -1,350 +1,180 @@ using System.Collections; -using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; -public class Player +public class Player : MonoBehaviour { + [Header("Player Settings")] + public int maxHealth = 10; // Starting health + private int currentHealth; + private bool isDead = false; // Tracks if the player is dead + private bool isPlaying = true; - //private Rigidbody2D r2d; - public float speed; - public int health; - - Vector2 movement; - Vector2 mousePos; - - public Rigidbody2D rb; - public Rigidbody2D rb2; - //public GameObject fireBallPrefab; - public GameObject damage; - public Camera camera; + [Header("Animation")] public Animator animator; - public GameObject Shooter; - //public Animation lightningAttack; - private Vector3 flashback; - public int element; - private bool Playing; - + [Header("UI & Elements")] public GameObject gameUI; + public GameObject shooter; + public GameObject gameOverUI; + + private Element currentElement = Element.Lightning; - //for SFX timing and looping - public AudioSource song1Intro; - public AudioSource song1Loop; - public AudioSource bossSongIntro; - public AudioSource bossSongLoop; - public float timer; - private float bossTimer; - private float songCount = 13.35f; - private float bossSongCount = 8.15f; - private int song1Change = 0; - private int bossSongChange = 0; - private bool bossSongStarted; - public AudioSource winSong; + [Header("Music & Sound")] + public AudioSource songIntro; + public AudioSource songLoop; + public AudioSource bossIntro; + public AudioSource bossLoop; + public AudioSource winMusic; - //public GameObject UI; + private bool isBossMusicPlaying = false; - - public float Deadtimer; - public bool isDead; - public float countdown; - public GameObject Reset; + [Header("Timers")] + public float deathCountdown = 3f; + private float deathTimer = 0f; - // Start is called before the first frame update - void Start() + private void Start() { - Playing=true; - element = 1; - animator.SetInteger("element", element); + currentHealth = maxHealth; + UpdateElement(currentElement); - //UI = GameObject.Find("PlayerUI"); + // Start music + if (songIntro != null) songIntro.Play(); + if (songLoop != null) songLoop.Stop(); + if (bossIntro != null) bossIntro.Stop(); + if (bossLoop != null) bossLoop.Stop(); + + isBossMusicPlaying = false; isDead = false; + isPlaying = true; } - // Update is called once per frame - void Update() + private void Update() { - if(Playing==true) - { - //input - movement.x = Input.GetAxisRaw("Horizontal"); - movement.y = Input.GetAxisRaw("Vertical"); - - mousePos = camera.ScreenToWorldPoint(Input.mousePosition); - - animator.SetFloat("Horizontal", movement.x); - animator.SetFloat("Vertical", movement.y); - animator.SetFloat("Speed", movement.sqrMagnitude); - - - if( Input.GetButtonDown("lightning")) - { - gameUI.SendMessage("ActiveElement", 1); - - element = 1; - animator.SetInteger("element", element); - } - - if( Input.GetButtonDown("fire")) - { - gameUI.SendMessage("ActiveElement", 2); - element = 2; - animator.SetInteger("element", element); - } - if( Input.GetButtonDown("ice")) + if (isDead) { - gameUI.SendMessage("ActiveElement", 3); - element = 3; - animator.SetInteger("element", element); - } - if( Input.GetButtonDown("earth")) - { - gameUI.SendMessage("ActiveElement", 4); - element = 4; - animator.SetInteger("element", element); + deathTimer += Time.deltaTime; + if (deathTimer >= deathCountdown) + { + LoadScene("Menu"); + } } + } - //attack Now Done in Shooter - //if( Input.GetButtonDown("Fire2")) - //{ - //Instantiate(fireBallPrefab, this.transform.position, Quaternion.identity); + private void UpdateElement(Element element) + { + currentElement = element; + animator.SetInteger("element", (int)element); - - //} - } - flashback = this.transform.position; - //print(flashback); - - + // Update UI for active element + gameUI?.SendMessage("ActiveElement", (int)element, SendMessageOptions.DontRequireReceiver); + } - if (timer >= songCount && song1Change == 0) - { - - song1Change = 1; - } - else if(song1Change == 0 && timer < songCount) + private void OnTriggerEnter2D(Collider2D collision) + { + if (collision.CompareTag("Enemy")) { - timer+= Time.deltaTime; + TakeDamage(1); } - - if (song1Change == 1) + else if (collision.CompareTag("EnemyProjectile")) { - - song1Intro.Stop(); - song1Loop.Play(); - song1Change = 2; + TakeDamage(1); + Destroy(collision.gameObject); } + } - if (bossSongStarted) - { - if (bossTimer >= bossSongCount && bossSongChange == 0) - { + private void TakeDamage(int damage) + { + if (isDead) return; - bossSongChange = 1; - } - else if (bossSongChange == 0 && bossTimer < bossSongCount) - { - bossTimer += Time.deltaTime; - } + currentHealth -= damage; + Debug.Log($"Player took {damage} damage. Remaining health: {currentHealth}"); - if (bossSongChange == 1) - { + // Notify UI of damage + gameUI?.SendMessage("Hurt", damage, SendMessageOptions.DontRequireReceiver); - bossSongIntro.Stop(); - bossSongLoop.Play(); - bossSongChange = 2; - } - } - - if(isDead == true) + if (currentHealth <= 0) { - Deadtimer += Time.deltaTime; + Die(); } - - if(Deadtimer>=countdown) + else { - Reset.SendMessage("LoadScene", "Menu"); + animator.Play($"{currentElement}Damage"); } - - - - } - void StartBossMusic() + public void HurtMe(int damage) { - song1Loop.Stop(); - bossSongIntro.Play(); - bossSongStarted = true; + TakeDamage(damage); // Simplify external damage calls } - void PlayWinSong() + private void Heal(int amount) { - song1Intro.Stop(); - song1Loop.Stop(); - bossSongIntro.Stop(); - bossSongLoop.Stop(); - winSong.Play(); + currentHealth = Mathf.Min(currentHealth + amount, maxHealth); + gameUI?.SendMessage("Heal", amount, SendMessageOptions.DontRequireReceiver); } - void FixedUpdate() + private void Die() { - if(Playing==true) - { - //movement - rb.MovePosition(rb.position + movement * speed *Time.fixedDeltaTime); - rb2.MovePosition(rb.position + movement * speed *Time.fixedDeltaTime); - - Vector2 lookDir = mousePos - rb.position; - float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg - 90f; - rb2.rotation = angle; - - } - - } + isDead = true; + isPlaying = false; + Debug.Log("Player is dead!"); - public void OnTriggerEnter2D(Collider2D other) + // Trigger shooter and death animations + shooter.SendMessage("Death"); + animator.Play("Death"); - { - if (other.gameObject.CompareTag("Enemy")) + // Show game over UI + if (gameOverUI != null) { - HurtMe(1); - //gameUI.SendMessage("Hurt", 1); - //this.transform.position -= this.transform.position - other.transform.position; + gameOverUI.SetActive(true); } - else if (other.gameObject.CompareTag("EnemyProjectile")) - { - HurtMe(1); - //gameUI.SendMessage("Hurt", 1); - if(health >= 1) - { - if(element == 1) - { - animator.Play("LightningDamage"); - } - if(element == 2) - { - animator.Play("FireDamage"); - } - if(element == 3) - { - animator.Play("IceDamage"); - } - if(element == 4) - { - animator.Play("EarthDamage"); - } - } - - - //print(health); - Destroy(other.gameObject); - } - } - - void Heal() + public void StartBossMusic() { - if(health < 5) + if (!isBossMusicPlaying) { - health = health+1; - gameUI.SendMessage("Heal", SendMessageOptions.DontRequireReceiver); - + songLoop.Stop(); + bossIntro.Play(); + StartCoroutine(PlayBossLoop()); + isBossMusicPlaying = true; } } - private void HurtMe(int damage) + private IEnumerator PlayBossLoop() { - health -= damage; - if (health <= 0) - { - Playing = false; - isDead = true; - Shooter.gameObject.SendMessage("Death"); - animator.Play("DEATH"); - gameUI.SendMessage("Hurt", damage); - - } - else if (health >= 1) - { - if (element == 1) - { - animator.Play("LightningDamage"); - gameUI.SendMessage("Hurt",damage); - } - if (element == 2) - { - animator.Play("FireDamage"); - gameUI.SendMessage("Hurt",damage); - } - if (element == 3) - { - animator.Play("IceDamage"); - gameUI.SendMessage("Hurt",damage); - } - if (element == 4) - { - animator.Play("EarthDamage"); - gameUI.SendMessage("Hurt",damage); - } - } + yield return new WaitForSeconds(bossIntro.clip.length); + bossIntro.Stop(); + bossLoop.Play(); } - public void LightningAttacks() + public void PlayWinMusic() { - - animator.Play("Lightning m1"); - + songIntro.Stop(); + songLoop.Stop(); + bossIntro.Stop(); + bossLoop.Stop(); + winMusic.Play(); } - public void FireAttacks() - { - - animator.Play("Fire m1"); - - } - - public void IceAttacks() + public void Win() { - - animator.Play("Ice m1"); - + isPlaying = false; + shooter.SendMessage("Win"); + animator.Play($"{currentElement}WIN"); } - public void EarthAttacks() + public void LoadScene(string sceneName) { - - animator.Play("Earth m1"); - + SceneManager.LoadScene(sceneName); } +} - public void Win() - { - Playing = false; - Shooter.gameObject.SendMessage("Win"); - - if(element == 1) - { - animator.Play("WIN! Lightning"); - } - if(element == 2) - { - animator.Play("FireWIN"); - } - if(element == 4) - { - animator.Play("EarthWIN"); - } - if(element == 3) - { - animator.Play("IceWIN"); - } - - } - - public void LoadScene(string sceneName) - { - SceneManager.LoadScene("Menu"); - } +public enum Element +{ + Lightning = 1, + Fire = 2, + Ice = 3, + Earth = 4 } diff --git a/Assets/Scripts/Player/PlayerMovement.cs b/Assets/Scripts/Player/PlayerMovement.cs new file mode 100644 index 0000000..332c313 --- /dev/null +++ b/Assets/Scripts/Player/PlayerMovement.cs @@ -0,0 +1,65 @@ +using UnityEngine; + +public class PlayerMovement : MonoBehaviour +{ + [Header("Movement Settings")] + public float speed = 5f; // Movement speed + + private Vector2 movement; // Stores input movement + private Rigidbody2D rb; // Reference to Rigidbody2D + private Animator animator; // Reference to Animator + + [Header("Mouse Rotation (Optional)")] + public bool rotateTowardsMouse = true; // Should the player rotate towards the mouse + private Camera mainCamera; // Main camera reference + + void Start() + { + // Get required components + rb = GetComponent(); + animator = GetComponent(); + mainCamera = Camera.main; // Cache the main camera + } + + void Update() + { + // Capture input + movement.x = Input.GetAxisRaw("Horizontal"); + movement.y = Input.GetAxisRaw("Vertical"); + + // Update animator with movement data + if (animator != null) + { + animator.SetFloat("Horizontal", movement.x); + animator.SetFloat("Vertical", movement.y); + animator.SetFloat("Speed", movement.sqrMagnitude); + } + } + + void FixedUpdate() + { + // Apply movement + if (rb != null) + { + Vector2 newPosition = rb.position + movement * speed * Time.fixedDeltaTime; + rb.MovePosition(newPosition); + } + + // Rotate towards the mouse if enabled + if (rotateTowardsMouse && mainCamera != null) + { + RotateTowardsMouse(); + } + } + + /// + /// Rotates the player to face the mouse position. + /// + private void RotateTowardsMouse() + { + Vector3 mousePosition = mainCamera.ScreenToWorldPoint(Input.mousePosition); + Vector2 lookDirection = mousePosition - transform.position; + float angle = Mathf.Atan2(lookDirection.y, lookDirection.x) * Mathf.Rad2Deg - 90f; + rb.rotation = angle; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Player/PlayerMovement.cs.meta b/Assets/Scripts/Player/PlayerMovement.cs.meta new file mode 100644 index 0000000..1328ad5 --- /dev/null +++ b/Assets/Scripts/Player/PlayerMovement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 069499c5bdd983b43ac6497d0888e432 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Player/Shooter.cs b/Assets/Scripts/Player/Shooter.cs index b880a67..4ff55e6 100644 --- a/Assets/Scripts/Player/Shooter.cs +++ b/Assets/Scripts/Player/Shooter.cs @@ -1,364 +1,220 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; -using System; public class Shooter : MonoBehaviour { - float speed; + // Movement and Components + private Rigidbody2D rb; + private Vector2 movement; - Vector2 Movement; - Rigidbody2D rb; - GameObject Player; - Transform SpellShooter; - - GameObject Projectile; - GameObject Projectile2; - GameObject firemagic; - GameObject lightningmagic; - GameObject icemagic; - GameObject earthmagic; + [SerializeField] private GameObject player; + [SerializeField] private Transform spellShooter; - GameObject firemagic2; - GameObject lightningmagic2; - GameObject icemagic2; - GameObject earthmagic2; + // Projectile Prefabs + [SerializeField] private GameObject firemagic; + [SerializeField] private GameObject lightningmagic; + [SerializeField] private GameObject icemagic; + [SerializeField] private GameObject earthmagic; + [SerializeField] private GameObject firemagic2; + [SerializeField] private GameObject lightningmagic2; + [SerializeField] private GameObject icemagic2; + [SerializeField] private GameObject earthmagic2; - GameObject Aim; - bool lightning; - bool fire; - bool ice; - bool earth; + private GameObject currentProjectile; + private GameObject currentProjectile2; + // Aiming + [SerializeField] private GameObject aim; - bool Playing; + // Audio + [SerializeField] private AudioSource iceM1; + [SerializeField] private AudioSource fireM1; + [SerializeField] private AudioSource lightningM1; + [SerializeField] private AudioSource earthM1; - float shotForce = 20f; - float shotForce2 = 20f; - - AudioSource IceM1; - AudioSource IceM2; - AudioSource FireM1; - AudioSource FireM2; - AudioSource LightningM1; - AudioSource LightningM2; - AudioSource EarthM1; - AudioSource EarthM2; + // Cooldowns + private bool fireReady = true; + private bool iceReady = true; + private bool lightningReady = true; + private bool earthReady = true; + [SerializeField] private GameObject gameUI; + // Current Element + private enum Element { Lightning, Fire, Ice, Earth } + private Element currentElement; - //cooldowns - float iceCooldown; - float fireCooldown; - float earthCooldown; - float lightningCooldown; - bool iceReady; - bool fireReady; - bool earthReady; - bool lightningReady; - GameObject GameUI; + // Shooting Force + private float shotForce = 20f; + private bool isPlaying = true; - - - public GameObject needsAimed; - private Vector2 shooterpos; - - - // Start is called before the first frame update void Start() { - Playing=true; - - Projectile = lightningmagic; - Projectile2 = lightningmagic2; - lightning = true; - fire = false; - ice = false; - earth = false; - - lightningReady = true; - iceReady = true; - fireReady = true; - earthReady = true; - + // Initialize to lightning by default + currentProjectile = lightningmagic; + currentProjectile2 = lightningmagic2; + currentElement = Element.Lightning; } - void Death() - { - Playing=false; - } - - - void Win() - { - Playing = false; - Aim.gameObject.SetActive(false); - } - // Update is called once per frame void Update() { + if (!isPlaying) return; + + // Handle movement input movement.x = Input.GetAxisRaw("Horizontal"); movement.y = Input.GetAxisRaw("Vertical"); - if( Input.GetButtonDown("lightning")) - { - Projectile = lightningmagic; - Projectile2 = lightningmagic2; - lightning = true; - fire = false; - ice = false; - earth = false; - - shotForce = 20f; - - } - if( Input.GetButtonDown("fire")) - { - Projectile = firemagic; - Projectile2 = firemagic2; - fire = true; - lightning = false; - ice = false; - earth = false; - - shotForce = 20f; - } - if( Input.GetButtonDown("ice")) - { - Projectile = icemagic; - Projectile2 = icemagic2; - ice = true; - fire = false; - lightning = false; - earth = false; + // Handle element switching + if (Input.GetButtonDown("lightning")) + SwitchElement(Element.Lightning); + if (Input.GetButtonDown("fire")) + SwitchElement(Element.Fire); + if (Input.GetButtonDown("ice")) + SwitchElement(Element.Ice); + if (Input.GetButtonDown("earth")) + SwitchElement(Element.Earth); + + // Handle shooting input + if (Input.GetButtonDown("M1")) + Shoot(); + if (Input.GetButtonDown("M2")) + Shoot2(); + } - shotForce = 20f; - shotForce2 = 0f; + void SwitchElement(Element element) + { + currentElement = element; - } - if( Input.GetButtonDown("earth")) + switch (element) { - Projectile = earthmagic; - Projectile2 = earthmagic2; - earth = true; - fire = false; - lightning = false; - ice = false; - - shotForce = 10f; - } + case Element.Lightning: + currentProjectile = lightningmagic; + currentProjectile2 = lightningmagic2; + shotForce = 20f; + break; + case Element.Fire: + currentProjectile = firemagic; + currentProjectile2 = firemagic2; + shotForce = 15f; + break; - //attack - if( Input.GetButtonDown("M1")) - { - //print ("M1"); - if(Playing==true) - { - Shoot(); - } - } + case Element.Ice: + currentProjectile = icemagic; + currentProjectile2 = icemagic2; + shotForce = 10f; + break; - if( Input.GetButtonDown("M2")) - { - //print ("M2"); - if(Playing==true) - { - Shoot2(); - } + case Element.Earth: + currentProjectile = earthmagic; + currentProjectile2 = earthmagic2; + shotForce = 10f; + break; } } - - void LightningEnable() - { - lightningReady = true; - print("lightning enable"); - print(lightningReady); - } - void IceEnable() - { - iceReady = true; - print("ice enable"); - print(iceReady); - } - void FireEnable() - { - fireReady = true; - print("fire enable"); - print(fireReady); - } - void EarthEnable() + void Shoot() { - earthReady = true; - print("earth enable"); - print(earthReady); + if (!CanShoot(currentElement)) return; + + GameObject bullet = Instantiate(currentProjectile, aim.transform.position, spellShooter.rotation); + Rigidbody2D rb = bullet.GetComponent(); + rb.AddForce(spellShooter.up * shotForce, ForceMode2D.Impulse); + + PlaySound(currentElement, true); + StartCooldown(currentElement); } - /* - void GetAim(GameObject other) + void Shoot2() { - other.SendMessage("GetAim", Shooter.up); + if (!CanShoot(currentElement)) return; + + GameObject bullet2 = Instantiate(currentProjectile2, aim.transform.position, spellShooter.rotation); + Rigidbody2D rb = bullet2.GetComponent(); + rb.AddForce(spellShooter.up * shotForce, ForceMode2D.Impulse); + + PlaySound(currentElement, false); + StartCooldown(currentElement); } - */ - void GetAim(GameObject other) + bool CanShoot(Element element) { - shooterpos = Shooter.up; - //print("get aim"); - //print("SpellShooter" + SpellShooter.up); - //print("SpellShooter" + Shooterpos); - //needsAimed = GameObject.Find("Fireball"); - //print(needsAimed); - other.SendMessage("GetAim", shooterpos); - //needsAimed.SendMessage("GetAim", SendMessageOptions.DontRequireReceiver); + switch (element) + { + case Element.Lightning: return lightningReady; + case Element.Fire: return fireReady; + case Element.Ice: return iceReady; + case Element.Earth: return earthReady; + default: return false; + } } - void Shoot() + + void StartCooldown(Element element) { - if (lightning == true) + switch (element) { - if (lightningReady) - { - shotForce = 20f; - lightningCooldown = 1f; - GameObject bullet = Instantiate(Projectile, Aim.transform.position, Shooter.rotation); - LightningM1.Play(); - player.GameObject.SendMessage("LightningAttacks"); - Rigidbody2D rb = bullet.GetComponent(); - rb.AddForce(ShooterThing.up * shotForce, ForceMode2D.Impulse); + case Element.Lightning: lightningReady = false; - gameUI.SendMessage("LightningCooldown", lightningCooldown); - - } - else - { - print(lightningReady); - } + StartCoroutine(CooldownTimer(1f, () => lightningReady = true)); + gameUI.SendMessage("LightningCooldown", 1f); + break; - } - - if(fire == true) - { - if (fireReady) - { - shotForce = 5f; - GameObject bullet = Instantiate(Projectile, Aim.transform.position, Shooter.rotation); + case Element.Fire: fireReady = false; - fireCooldown = 1.5f; - gameUI.SendMessage("FireCooldown", fireCooldown); - FireM1.Play(); - player.GameObject.SendMessage("FireAttacks"); - Rigidbody2D rb = bullet.GetComponent(); - rb.AddForce(ShooterThing.up * shotForce, ForceMode2D.Impulse); + StartCoroutine(CooldownTimer(1.5f, () => fireReady = true)); + gameUI.SendMessage("FireCooldown", 1.5f); + break; - } - - } - - if(ice == true) - { - if (iceReady) - { - shotForce = 15f; - GameObject bullet = Instantiate(Projectile, Aim.transform.position, Shooter.rotation); + case Element.Ice: iceReady = false; - iceCooldown = .5f; - gameUI.SendMessage("IceCooldown", iceCooldown); - IceM1.Play(); - player.GameObject.SendMessage("IceAttacks"); - Rigidbody2D rb = bullet.GetComponent(); - rb.AddForce(ShooterThing.up * shotForce, ForceMode2D.Impulse); - - } + StartCoroutine(CooldownTimer(0.5f, () => iceReady = true)); + gameUI.SendMessage("IceCooldown", 0.5f); + break; - } - - if(earth == true) - { - if (earthReady) - { - shotForce = 10f; - GameObject bullet = Instantiate(Projectile, Aim.transform.position, Shooter.rotation); + case Element.Earth: earthReady = false; - earthCooldown = 1.5f; - gameUI.SendMessage("EarthCooldown", earthCooldown); - EarthM1.Play(); - player.GameObject.SendMessage("EarthAttacks"); - Rigidbody2D rb = bullet.GetComponent(); - rb.AddForce(ShooterThing.up * shotForce, ForceMode2D.Impulse); - - } - + StartCoroutine(CooldownTimer(1.5f, () => earthReady = true)); + gameUI.SendMessage("EarthCooldown", 1.5f); + break; } } - void Shoot2() + private IEnumerator CooldownTimer(float cooldownTime, System.Action resetAction) { - //LightningAttack2 - if(lightning == true) - { - if (lightningReady) - { - lightningReady = false; - lightningCooldown = 3f; - GameUI.SendMessage("LightningCooldown", lightningCooldown); - //LightningM2.Play(); - GameObject bullet2 = Instantiate(Projectile2, Aim.transform.position, Shooter.rotation); - player.GameObject.SendMessage("LightningAttacks"); - } + yield return new WaitForSeconds(cooldownTime); + resetAction(); + } - } - //FireAttack2 - if(fire == true) + void PlaySound(Element element, bool isPrimary) + { + switch (element) { - if (fireReady) - { - shotForce = 5f; - fireReady = false; - fireCooldown = 3f; - GameUI.SendMessage("FireCooldown", fireCooldown); - FireM2.Play(); - GameObject bullet2 = Instantiate(Projectile2, Aim.transform.position, Shooter.rotation); - player.GameObject.SendMessage("FireAttacks"); - Rigidbody2D rb = bullet2.GetComponent(); - rb.AddForce(ShooterThing.up * shotForce, ForceMode2D.Impulse); - } - + case Element.Lightning: + if (isPrimary) lightningM1.Play(); + break; + case Element.Fire: + if (isPrimary) fireM1.Play(); + break; + case Element.Ice: + if (isPrimary) iceM1.Play(); + break; + case Element.Earth: + if (isPrimary) earthM1.Play(); + break; } - //IceAttack2 - if(ice == true) - { - if (iceReady) - { - iceReady = false; - iceCooldown = 4f; - GameUI.SendMessage("IceCooldown", iceCooldown); - //IceM2.Play(); - GameObject bullet2 = Instantiate(Projectile2, Aim.transform.position, Shooter.rotation); - player.GameObject.SendMessage("IceAttacks"); - } + } - } - //EarthAttack2 - if(earth == true) - { - if (earthReady) - { - earthReady = false; - earthCooldown = 5f; - GameUI.SendMessage("EarthCooldown", earthCooldown); - //EarthM2.Play(); - GameObject bullet2 = Instantiate(Projectile2, Aim.transform.position, Shooter.rotation); - player.gameObject.SendMessage("EarthAttacks"); - } + public void Death() + { + isPlaying = false; + } - } - void HurtMe(int damage) - { - //stupid puddle sends to this instead of player - player.SendMessage("HurtMe", 1); - } + public void Win() + { + isPlaying = false; + aim.SetActive(false); } } \ No newline at end of file diff --git a/Assets/Tutorial.cs b/Assets/Tutorial.cs index 1217245..194db89 100644 --- a/Assets/Tutorial.cs +++ b/Assets/Tutorial.cs @@ -1,107 +1,149 @@ using System.Collections; using System.Collections.Generic; -using UnityEngine.SceneManagement; using UnityEngine; +using UnityEngine.SceneManagement; - -public class Tutorial +public class Tutorial : MonoBehaviour { - public float time; - public int movespeed = 3; + [Header("Movement Settings")] + public float moveSpeed = 3f; public Vector3 userDirection = Vector3.one; - public bool move; + private bool move = true; - public bool allowinput; + [Header("Tutorial Flow")] + public bool allowInput = false; public GameObject inputTUT; - public Animator animator; - public int tutorialNum; - public GameObject tutscreen1; - public GameObject tutscreen2; - public GameObject tutscreen3; - public GameObject tutscreen4; - //public Transform duckHuntDog; - - // Start is called before the first frame update + public int tutorialNum = 0; + public GameObject[] tutorialScreens; // Array to hold tutorial screens + public float time = 0f; + void Start() { - move=true; - allowinput=false; - tutorialNum=0; - } + // Initialize settings + move = true; + allowInput = false; + tutorialNum = 0; - // Update is called once per frame - void Update() - { - time+=Time.deltaTime; + // Deactivate all tutorial screens + foreach (GameObject screen in tutorialScreens) + { + screen.SetActive(false); + } - if(this.transform.position.x >= 0) + // Deactivate input tutorial UI + if (inputTUT != null) { - move=false; - //print("yay"); - userDirection.x=0; - //animator.Play("DuckTalk"); - + inputTUT.SetActive(false); } - if(move=true) + } + + void Update() + { + // Increment time + time += Time.deltaTime; + + // Handle movement + if (move) { - transform.Translate(userDirection * movespeed * Time.deltaTime); + transform.Translate(userDirection * moveSpeed * Time.deltaTime); + + if (transform.position.x >= 0) + { + move = false; + userDirection = Vector3.zero; // Stop movement + } } - if(time >= 4f && time < 5f) + + // Trigger tutorial screen and input tutorial after 4 seconds + if (time >= 4f && time < 5f) { - tutscreen1.SetActive(true); - inputTUT.SetActive(true); - animator.Play("DuckTalk"); + ShowTutorialScreen(0); + if (inputTUT != null) + { + inputTUT.SetActive(true); + } + if (animator != null) + { + animator.Play("DuckTalk"); + } + allowInput = true; // Allow input for progression } - if(allowinput=true) + // Handle input progression + if (allowInput) { - if( Input.GetButtonDown("Fire2")) + // Advance tutorial on "Fire2" input + if (Input.GetButtonDown("Fire2")) { - tutorialNum+=1; + AdvanceTutorial(); } - if( Input.GetButtonDown("M2")) - { - if(time> 4f) - { - tutorialNum = 20; - } - - } + // Skip tutorial on "M2" input + if (Input.GetButtonDown("M2") && time > 4f) + { + SkipTutorial(); + } + } + } + private void ShowTutorialScreen(int screenIndex) + { + // Deactivate all screens first + foreach (GameObject screen in tutorialScreens) + { + screen.SetActive(false); } - - /*if(tutorialNum == 1) + // Activate the desired screen + if (screenIndex >= 0 && screenIndex < tutorialScreens.Length) + { + tutorialScreens[screenIndex].SetActive(true); + } + } + + private void AdvanceTutorial() + { + tutorialNum++; + + if (tutorialNum < tutorialScreens.Length) { - tutscreen1.SetActive(true); - }*/ - if(tutorialNum == 1) + ShowTutorialScreen(tutorialNum); + } + else { - tutscreen1.SetActive(false); - tutscreen2.SetActive(true); + EndTutorial(); } - if(tutorialNum == 2) + } + + private void SkipTutorial() + { + tutorialNum = 20; // Special skip case + if (animator != null) { - tutscreen2.SetActive(false); - tutscreen3.SetActive(true); + animator.Play("DuckOw"); } - if(tutorialNum == 3) + // Deactivate all screens + foreach (GameObject screen in tutorialScreens) { - tutscreen3.SetActive(false); - tutscreen4.SetActive(true); + screen.SetActive(false); } + } - if(tutorialNum ==20) + private void EndTutorial() + { + // Deactivate all tutorial elements + foreach (GameObject screen in tutorialScreens) { - animator.Play("DuckOw"); - tutscreen1.SetActive(false); - tutscreen2.SetActive(false); - tutscreen3.SetActive(false); - tutscreen4.SetActive(false); + screen.SetActive(false); + } + + if (inputTUT != null) + { + inputTUT.SetActive(false); } + Debug.Log("Tutorial Ended"); } } \ No newline at end of file