As one of the core concepts of our game we wanted more than just a health bar but also an oxygen bar that drains periodically throughout the gameplay. The following script does this, every second the oxygen drains by one and if the oxygen runs out then it is game over, additionally when the plays oxygen drops below 60, dialogue will trigger in the game and the AI voice in the players suit will begin to taunt the player.
public class OxygenManager : MonoBehaviour
{
public static OxygenManager Instance { get; private set; }
public Slider OxygenBar;
public float RepeatDelay = 1.0f;
private void Awake() {
if (Instance != null && Instance != this) {
Destroy(gameObject);
}
Instance = this;
}
void Start()
{
OxygenBar.maxValue = PlayerController.Instance.MaxOxygen;
OxygenBar.value = PlayerController.Instance.Oxygen;
//InvokeRepeating("DecreaseOxygen", RepeatDelay, 1.0f);
StartCoroutine(DecreaseOxygenCoroutine());
}
// Update is called once per frame
void Update()
{
if (PlayerController.Instance.IsTalking) {
RepeatDelay = 10000f;
} else {
RepeatDelay = 1f;
}
}
public void DecreaseOxygen() {
PlayerController.Instance.Oxygen -= 1;
OxygenBar.value -= 1;
}
public void IncreaseOxygen() {
OxygenBar.value = PlayerController.Instance.Oxygen;
}
public IEnumerator DecreaseOxygenCoroutine() {
while (true) {
if (PlayerController.Instance.IsTalking == false) {
DecreaseOxygen();
yield return new WaitForSeconds(1);
} else {
yield return new WaitForSeconds(1);
}
}
}
}
Within the game there are oxygen pickups within the world, when the play enters this trigger, they will be given a set amount of oxygen which is set by the designer in the inspector up to the max oxygen value.
public class OxygenPickup : MonoBehaviour
{
[SerializeField] private float AdditionalOxygen;
private void OnTriggerEnter2D(Collider2D collision) {
if (collision.CompareTag("Player")) {
PlayerController.Instance.Oxygen += AdditionalOxygen;
OxygenManager.Instance.IncreaseOxygen();
this.GetComponent<AudioSource>().Play();
this.GetComponent<BoxCollider2D>().enabled = false;
this.GetComponent<SpriteRenderer>().enabled = false;
Destroy(this.gameObject, 3);
}
}
}
Although we debated about the player being able to heal it was decided that we wanted a way for the player to heal within the game. The way we heal within the game are these set healing locations, each location will have a limited number of uses so the player needs to use them sparingly. When the player enters the healing station they can press F to heal, the amount of health they gain is determined by the variable HealAmount and they are healed up to a certain value.
public class HealingStation : MonoBehaviour
{
public int HealAmmount;
[SerializeField] private GameObject HealText;
public int NoOfUses;
private void OnTriggerEnter2D(Collider2D collision) {
if (collision.gameObject.CompareTag("Player")) {
HealText.SetActive(true);
}
}
private void OnTriggerStay2D(Collider2D collision) {
if (collision.gameObject.CompareTag("Player")) {
if (Input.GetKey(KeyCode.F) && NoOfUses > 0) {
if((PlayerController.Instance.Health + HealAmmount) > PlayerController.Instance.MaxHealth) {
PlayerController.Instance.Health = PlayerController.Instance.MaxHealth;
NoOfUses -= 1;
} else if ((PlayerController.Instance.Health + HealAmmount) < PlayerController.Instance.MaxHealth) {
PlayerController.Instance.Health += HealAmmount;
NoOfUses -= 1;
}
this.GetComponent<AudioSource>().Play();
StartCoroutine(PlayerController.Instance.ChangeSpriteColour(Color.green, 3f));
}
}
}
private void OnTriggerExit2D(Collider2D collision) {
if (collision.gameObject.CompareTag("Player")) {
HealText.SetActive(false);
}
}
}
We wanted some form of a dialogue system within the game to inform the player what was happening within the world. The following is how it works, the use will create a text file in the following format;
NAME | HELLO WORLD
The ‘|’ character is used to seperate the name of the person talking from the dialogue. This text file is then parsed and the names are saved to a string array and the dialogue to another string array. When it comes time to display the dialogue, each line is written to the screen via a queue and then removed from the queue.
The reason the dialogue was implemented this way was due to it being easier to edit text files for the designers as they would just need to create/edit files and then drag the corresponding text file into the inspector.