From d3f4993404ecb7bfff5add67d5f73c6f571dc4e8 Mon Sep 17 00:00:00 2001 From: Trianta <56975502+Trimutex@users.noreply.github.com> Date: Thu, 14 Mar 2024 18:40:19 -0500 Subject: [PATCH] Added base damage to enemy health --- Assets/__Scripts/Enemy.cs | 65 ++++++++++++++++++++---- Assets/__Scripts/Enemy_4.cs | 92 ++++++++++++++++++++++++++++++++++ Assets/__Scripts/Main.cs | 4 ++ Assets/__Scripts/Utils.cs | 19 +++++++ Assets/__Scripts/Utils.cs.meta | 11 ++++ 5 files changed, 181 insertions(+), 10 deletions(-) create mode 100644 Assets/__Scripts/Utils.cs create mode 100644 Assets/__Scripts/Utils.cs.meta diff --git a/Assets/__Scripts/Enemy.cs b/Assets/__Scripts/Enemy.cs index 806375a..f622d6d 100644 --- a/Assets/__Scripts/Enemy.cs +++ b/Assets/__Scripts/Enemy.cs @@ -9,10 +9,23 @@ public class Enemy : MonoBehaviour public float fireRate = 0.3f; // Seconds/shot (Unused) public float health = 10; public int score = 100; // Points earned for destroying this + public float showDamageDuration = 0.1f; + [Header("Set Dynamically: Enemy")] + public Color[] originalColors; + public Material[] materials; + public bool showingDamage = false; + public float damageDoneTime; + public bool notifiedOfDestruction = false; protected BoundsCheck bndCheck; void Awake() { bndCheck = GetComponent(); + // Get materials and colors for this GameObject and its children + materials = Utils.GetAllMaterials(gameObject); + originalColors = new Color[materials.Length]; + for (int i = 0; i < materials.Length; ++i) { + originalColors[i] = materials[i].color; + } } // This is a Property: A method that acts like a field @@ -33,24 +46,56 @@ public class Enemy : MonoBehaviour void OnCollisionEnter(Collision coll) { GameObject otherGO = coll.gameObject; - if (otherGO.tag == "ProjectileHero") { - Destroy(otherGO); // Destroy the Projectile - Destroy(gameObject); // Destroy this Enemy GameObject - } else { - print("Enemy hit by non-ProjectileHero: " + otherGO.name); + switch (otherGO.tag) { + case "ProjectileHero": + Projectile p = otherGO.GetComponent(); + // If this Enemy is off screen, don't damage it. + if (!bndCheck.isOnScreen) { + Destroy(otherGO); + break; + } + + // Hurt this Enemy + ShowDamage(); + health -= 1; + if (health <= 0) { + if (!notifiedOfDestruction) { + Main.S.ShipDestroyed(this); + } + notifiedOfDestruction = true; + // Destroy this Enemy + Destroy(this.gameObject); + } + Destroy(otherGO); + break; + + default: + print("Enemy hit by non-ProjectileHero: " + otherGO.name ); + break; } } - // Start is called before the first frame update - void Start() - { - + void ShowDamage() { + foreach(Material m in materials) { + m.color = Color.red; + } + showingDamage = true; + damageDoneTime = Time.time + showDamageDuration; + } + + void UnShowDamage() { + for (int i = 0; i < materials.Length; ++i) { + materials[i].color = originalColors[i]; + } + showingDamage = false; } - // Update is called once per frame void Update() { Move(); + if (showingDamage && Time.time > damageDoneTime) { + UnShowDamage(); + } if (bndCheck != null && bndCheck.offDown) { // We're off the bottom, so destroy this GameObject Destroy(gameObject); diff --git a/Assets/__Scripts/Enemy_4.cs b/Assets/__Scripts/Enemy_4.cs index 5c1506b..19a10a9 100644 --- a/Assets/__Scripts/Enemy_4.cs +++ b/Assets/__Scripts/Enemy_4.cs @@ -64,4 +64,96 @@ public class Enemy_4 : Enemy u = 1 - Mathf.Pow(1 - u, 2); // Apply East Out easing to u pos = (1 - u) * p0 + u*p1; // Simple linear interpolation } + + // These two functions find a Part in parts based on name or GameObject + Part FindPart(string n) { + foreach(Part prt in parts) { + if (prt.name == n) { + return prt; + } + } + return null; + } + + Part FindPart(GameObject go) { + foreach(Part prt in parts) { + if (prt.go == go) { + return prt; + } + } + return null; + } + + // These functions return true if the Part has been destroyed + bool Destroyed(GameObject go) { + return Destroyed(FindPart(go)); + } + + bool Destroyed(string n) { + return Destroyed(FindPart(n)); + } + + bool Destroyed(Part prt) { + if (prt == null) { + return true; + } + return prt.health <= 0; + } + + // This changes the color of just one Part to red instead of the whole ship + void ShowLocalizedDamage(Material m) { + m.color = Color.red; + damageDoneTime = Time.time + showDamageDuration; + showingDamage = true; + } + + // This will override the OnCollisionEnter that is part of Enemy.cs + void OnCollisionEnter(Collision coll) { + GameObject other = coll.gameObject; + switch (other.tag) { + case "ProjectileHero": + Projectile p = other.GetComponent(); + // If this Enemy is off screen, don't damage it. + if (!bndCheck.isOnScreen) { + Destroy(other); + break; + } + // Hurt this Enemy + GameObject goHit = coll.contacts[0].thisCollider.gameObject; + Part prtHit = FindPart(goHit); + if (prtHit == null) { + goHit = coll.contacts[0].otherCollider.gameObject; + prtHit = FindPart(goHit); + } + // Check whether this part is still protected + if (prtHit.protectedBy != null) { + foreach(string s in prtHit.protectedBy) { + // If one of the protecting parts hasn't been destroyed... + if (!Destroyed(s)) { + // ...then don't damage this part yet + Destroy(other); + return; + } + } + } + prtHit.health -= 1; + ShowLocalizedDamage(prtHit.mat); + if (prtHit.health <= 0) { + prtHit.go.SetActive(false); + } + bool allDestroyed = true; + foreach (Part prt in parts) { + if (!Destroyed(prt)) { + allDestroyed = false; + break; + } + } + if (allDestroyed) { + Main.S.ShipDestroyed(this); + Destroy(this.gameObject); + } + Destroy(other); + break; + } + } } diff --git a/Assets/__Scripts/Main.cs b/Assets/__Scripts/Main.cs index 4855c02..16c36d0 100644 --- a/Assets/__Scripts/Main.cs +++ b/Assets/__Scripts/Main.cs @@ -12,6 +12,10 @@ public class Main : MonoBehaviour public float enemyDefaultPadding = 1.5f; private BoundsCheck bndCheck; + public void ShipDestroyed(Enemy e) { + // Potentially generate a Powerup + } + void Awake() { S = this; // Set bndCheck to reference the BoundsCheck component of this GameObject diff --git a/Assets/__Scripts/Utils.cs b/Assets/__Scripts/Utils.cs new file mode 100644 index 0000000..73935aa --- /dev/null +++ b/Assets/__Scripts/Utils.cs @@ -0,0 +1,19 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class Utils : MonoBehaviour +{ + + // Returns a list of all Materials on this GameObject and its children + static public Material[] GetAllMaterials(GameObject go) { + Renderer[] rends = go.GetComponentsInChildren(); + + List mats = new List(); + foreach(Renderer rend in rends) { + mats.Add(rend.material); + } + + return(mats.ToArray()); + } +} diff --git a/Assets/__Scripts/Utils.cs.meta b/Assets/__Scripts/Utils.cs.meta new file mode 100644 index 0000000..513867e --- /dev/null +++ b/Assets/__Scripts/Utils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1443ee9b4e9c59bb8a6ccc76415bb003 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: