Decrease Lives on collision
I'm fairly new to Unity & C#, i've made a basic Flappy Bird type clone which runs perfect on WebGL, Windows & Android. I have decided to spruce it up a little and add in levels - after reaching a set score on each level the player advances. This component runs well as expected, I also want to implement a life system where if the player dies then it should decrease life by 1, so 3 lives max each time you die that value decreases by -1. Upon reaching -1 lives then the game will load up a game over screen and then head to the menu.
What my problem is, is I can't for the life of me figure out how to decrease my life. I have tried adding it to the OnCollisionEnter2D(); part of the script by using lives -= 1; it doesn't work, and if i add to the void Die() it also doesn't work.
The only way I have got this to work is by using an OnGUI code, is there anyway i can use it via using Unitys UI like i have done for a score and highscore?
My code is as follows...
using UnityEngine;
using UnityEngine.UI;
public class Playera : MonoBehaviour
{
// The force which is added when the player jumps
// This can be changed in the Inspector pannel
public Vector2 jumpForce = new Vector2(0,300);
// Lives settings
public float lives = 3;
public Text livesText;
void Start (){
// Set Live GUI
if(livesText.name == "livesText")
{
livesText.text = "Lives:" + lives;
}
}
// Update is called once per frame
void Update ()
{
// Jump
if (Input.GetKeyUp("space"))
{
GetComponent<Rigidbody2D>().velocity = Vector2.zero;
GetComponent<Rigidbody2D>().AddForce(jumpForce);
GetComponent<AudioSource>().Play(); // Plays Audio clip attached to GameObject
}
// Touch Controls
if (Input.GetMouseButtonUp(0))
{
GetComponent<Rigidbody2D>().velocity = Vector2.zero;
GetComponent<Rigidbody2D>().AddForce(jumpForce);
GetComponent<AudioSource>().Play(); // Plays the audio clip that is attached to gameobject
}
// Die by being off screen
Vector2 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
if (screenPosition.y > Screen.height || screenPosition.y < 0)
{
Die ();
}
// Exit Game
if (Input.GetKey("escape"))
{
Application.Quit();
}
// Save Lives
PlayerPrefs.SetFloat ("Lives", lives);
PlayerPrefs.Save();
}
// Die by collision
void OnCollisionEnter2D(Collision2D other)
{
Die();
}
// What happens when Die is called
void Die()
{
lives -= 1;
Application.LoadLevel("Level0");
}
}
If i was to use the OnGUI code i would take out the void Start function and replace with void OnGUI () { GUI.color = Color.black; GUILayout.Label(" Lives: " + lives.ToString()); }
Any help is appreciated
Try placing a debug statement in OnCollisionEnter2D(). Something like
Debug.Log("Playera.OnCollisionEnter2D() entered");
This is to deter$$anonymous$$e if OnCollisionEnter2D() actually entered". Also, what version of Unity are you using?
I will place the Debug as suggested, but i am pretty sure onCollisionEnter works because Die(); is being called, upon void Die() the level restarts, that element works fine, it's just not decreasing the value by -1. I have deleted the Application.LoadLevel("mylevel"); statement, and just kept the lives -=1; statement and it's not working, but using the OnGUI statement and it works fine, just not by using Unity's UI.
Okay i solved it by removing the offending code and rewriting it again in the Update function.
Now i have a new issue, when the lives reach below 0 (-1) the scene will change to the gameover scene - this works fine, i did receive an unwanted bug whereby every time i then reloaded the level it would automatically change to the gameover screen, this is because PlayerPrefs is being called in the Start Function to grab how many lives remain ( my Die function states that each time the player dies it has to take -1 life and reset the level so i needed PlayerPrefs to save and then load this float). So i solved this by adding in the following method in the Update function
// Save Lives
PlayerPrefs.SetFloat ("Lives", lives);
PlayerPrefs.Save();
// Call Game Over Screen after depleting lives
if(lives <=-1) // If lives reach below 0
{
PlayerPrefs.Delete$$anonymous$$ey("Lives"); // Deletes the saved player pref for lives
Application.LoadLevel("GameOver"); // Loads game over screen
}
This script runs great, however the issue i have is now is that everytime PlayerPrefs deletes the "lives" key, when the game restarts lives are at 0 ins$$anonymous$$d of the set 3 in the float. $$anonymous$$y full code is as follows. If anyone wishes to use the code themselves then feel free, but note it will need some reworking due to the errors mentioned above. (I will post full code in next comment)
using UnityEngine;
using UnityEngine.UI;
public class Playera : $$anonymous$$onoBehaviour
{
// The force which is added when the player jumps
// This can be changed in the Inspector pannel
public Vector2 jumpForce = new Vector2(0,300);
// Lives settings
public float lives = 3;
public Text livesText;
void Start ()
{
PlayerPrefs.GetFloat("Lives");
lives = PlayerPrefs.GetFloat("Lives");
}
// Update is called once per frame
void Update ()
{
// Lives UI
if(livesText.name == "livesText")
{
livesText.text = "Lives: " + lives;
}
// Jump
if (Input.Get$$anonymous$$eyUp("space"))
{
GetComponent<Rigidbody2D>().velocity = Vector2.zero;
GetComponent<Rigidbody2D>().AddForce(jumpForce);
GetComponent<AudioSource>().Play(); // Plays Audio clip attached to GameObject
}
// Touch Controls
if (Input.Get$$anonymous$$ouseButtonUp(0))
{
GetComponent<Rigidbody2D>().velocity = Vector2.zero;
GetComponent<Rigidbody2D>().AddForce(jumpForce);
GetComponent<AudioSource>().Play(); // Plays the audio clip that is attached to gameobject
}
// Die by being off screen
Vector2 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
if (screenPosition.y > Screen.height || screenPosition.y < 0)
{
Die ();
}
// Exit Game
if (Input.Get$$anonymous$$ey("escape"))
{
Application.Quit();
}
// Save Lives
PlayerPrefs.SetFloat ("Lives", lives);
PlayerPrefs.Save();
// Call Game Over Screen afer depleating lives
if(lives <=-1) // If lives reach below 0
{
PlayerPrefs.Delete$$anonymous$$ey("Lives"); // Deletes the saved player pref for lives
Application.LoadLevel("GameOver"); // Loads game over screen
}
}
// Die by collision
void OnCollisionEnter2D(Collision2D other)
{
Die();
}
// What happens when Die is called
void Die()
{
lives -= 1;
Application.LoadLevel("Level1a");
}
}
I seem to be solving this out all on my own lol, amazing what Google and Unity Scripting Reference can do. I solved the error quite simply by changing out PlayerPrefs.Delete$$anonymous$$ey("lives);
to PlayerPrefs.SetFloat("lives", 3);
What the code now does is upon colliding with my polygon colider it takes -1 away from the life score, once that score reaches -1 it then states that the Float is changed back to 3, and the scene changes to the game over scene.
Answer by lehart · Sep 26, 2016 at 03:54 PM
Finally finished the game, thanks for all the help and advice. You can grab a copy of the game for free below