Continuing my trend of trying to expand on these challenges I made a health system that can be added to the player and enemy. Before looking at the title of the next lesson I created a particle effect that plays when something with health takes damage so I’m excited to see how Rick approaches it!
If anyone would like to see the video,
I created the following scripts
Health - placed on the player and enemies, tuned for specific needs.
using System.Collections;
using UnityEngine;
public class Health : MonoBehaviour
{
[SerializeField] int health = 3;
[SerializeField] GameObject damagedEffects;
GameSession gameSession;
bool hasBeenHit = false;
void Start()
{
gameSession = FindObjectOfType<GameSession>();
}
private void Die()
{
if (tag == ("Player"))
{
ProcessPlayerDeath();
}
else
{
ProcessEnemyDeath();
}
}
private void ProcessEnemyDeath()
{
Destroy(gameObject);
}
public void TakeDamage()
{
if (!hasBeenHit)
{
damagedEffects.GetComponent<DamagedEffects>().SetEffectsPosition();
damagedEffects.SetActive(true);
health--;
hasBeenHit = true;
StartCoroutine(DelayEmissionDisable());
StartCoroutine(DelayCanBeHurt());
if (health <= 0)
{
Die();
}
}
}
IEnumerator DelayCanBeHurt()
{
yield return new WaitForSeconds(1f);
hasBeenHit = false;
}
IEnumerator DelayEmissionDisable()
{
yield return new WaitForSeconds(3f);
damagedEffects.SetActive(false);
}
void ProcessPlayerDeath()
{
gameSession.HandleLose();
}
}
Game Session - I placed this script on an empty game object ( Don’t worry Rick, I reset the transform!)
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class GameSession : MonoBehaviour
{
[SerializeField] PlayerController player;
[SerializeField] float loadDelay = 1f;
private void Start()
{
if (!player)
{
player = FindObjectOfType<PlayerController>();
}
}
public void HandleLose()
{
player.isAlive = false;
StartCoroutine(ReloadLevel());
}
IEnumerator ReloadLevel()
{
yield return new WaitForSeconds(loadDelay);
int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
SceneManager.LoadScene(currentSceneIndex);
}
void LoadNextLevel()
{
int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
int nextScene = currentSceneIndex +1;
if(nextScene == SceneManager.sceneCountInBuildSettings)
{
nextScene = 0;
}
SceneManager.LoadScene(nextScene);
}
}
Collision Handler - Attached only to the player
using UnityEngine;
public class CollisonHandler : MonoBehaviour
{
[SerializeField] Health playerHealth;
private void Start()
{
playerHealth = GetComponent<Health>();
}
private void OnTriggerEnter(Collider other)
{
Debug.Log(other.gameObject.name);
playerHealth.TakeDamage();
}
}
A script to manage the particle effect’s position and is attached to a game object with a particle system, I called it DamagedEffects.
using UnityEngine;
public class DamagedEffects : MonoBehaviour
{
[SerializeField] GameObject character;
public void SetEffectsPosition()
{
transform.localPosition = new Vector3(character.transform.localPosition.x, character.transform.localPosition.y, transform.localPosition.z);
}
}
And my enemy script looks like this
using UnityEngine;
public class Enemy : MonoBehaviour
{
Health health;
private void Start()
{
health = GetComponent<Health>();
}
private void OnParticleCollision(GameObject other)
{
Color newColor = new Color(Random.value, Random.value, Random.value, 1.0f);
GetComponent<Renderer>().material.color = newColor;
Debug.Log($"{name}I'm hit! by {other.gameObject.name}");
if (health)
{
health.TakeDamage();
}
}
}
I’m not sure if any of this will help anyone but I had fun making it and was proud of it so I felt like sharing!
Thanks guys!
edit- I only realized after posting that the video doesn’t actually show my level reload happening but I can assure you that it works