- Home /
Question not ansered yet
Error In Lives While Respawning
Hello Everyone! I'm making a 2 D plat former. When my player dies(falls below the ground the Lives decreases as 3,2,1,-1 & it should be 3,2,1,0. I am in this problem since the last month. I'm posting the codes below the Player controller and level manager script.
PLEASE PLEASE HELP ME!
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour {
public float moveSpeed;
public Rigidbody2D myRigidbody;
public float jumpSpeed;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask whatIsGround;
public bool isGrounded;
private Animator myAnim;
private Vector3 initScale;
public Vector3 respawnPosition;
public LevelManager theLevelManager;
public GameObject stompBox;
public float knockbackForce;
public float knockbackLength;
public float knockbackCounter;
public float invincibilityLength;
private float invincibilityCounter;
// Use this for initialization
void Start ()
{
myRigidbody = GetComponent<Rigidbody2D> ();
myAnim = GetComponent<Animator> ();
initScale = transform.localScale;
respawnPosition = transform.position;
theLevelManager = FindObjectOfType<LevelManager>();
}
// Update is called once per frame
void Update () {
isGrounded = Physics2D.OverlapCircle (groundCheck.position, groundCheckRadius, whatIsGround);
if (knockbackCounter <= 0)
{
if (Input.GetAxisRaw ("Horizontal") > 0f)
{
myRigidbody.velocity = new Vector3 (moveSpeed, myRigidbody.velocity.y, 0f);
transform.localScale = new Vector3 (1f, 1f, 1f);
transform.localScale = new Vector3 (initScale.x, initScale.y, initScale.z);
} else if (Input.GetAxisRaw ("Horizontal") < 0f) {
myRigidbody.velocity = new Vector3 (-moveSpeed, myRigidbody.velocity.y, 0f);
transform.localScale = new Vector3 (-1f, 1f, 1f);
transform.localScale = new Vector3 (-initScale.x, initScale.y, initScale.z);
} else {
myRigidbody.velocity = new Vector3 (0f, myRigidbody.velocity.y, 0f);
}
if (Input.GetButtonDown ("Jump") && isGrounded)
{
myRigidbody.velocity = new Vector3 (myRigidbody.velocity.x, jumpSpeed, 0f);
}
}
if (knockbackCounter > 0)
{
knockbackCounter -= Time.deltaTime;
if (transform.localScale.x > 0)
{
myRigidbody.velocity = new Vector3 (-knockbackForce, knockbackForce, 0f);
} else {
myRigidbody.velocity = new Vector3 (knockbackForce, knockbackForce, 0f);
}
}
if (invincibilityCounter > 0)
{
invincibilityCounter -= Time.deltaTime;
}
if (invincibilityCounter <= 0)
{
theLevelManager.invincible = false;
}
myAnim.SetFloat ("Speed", Mathf.Abs (myRigidbody.velocity.x));
myAnim.SetBool ("Grounded", isGrounded);
if (myRigidbody.velocity.y < 0)
{
stompBox.SetActive(true);
}else {
stompBox.SetActive (false);
}
}
public void Knockback()
{
knockbackCounter = knockbackLength;
invincibilityCounter = invincibilityLength;
theLevelManager.invincible = true;
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "KillPlane")
{
//gameObject.SetActive (false);
//transform.position = respawnPosition;
theLevelManager.Respawn ();
//theLevelManager.healthCount = 0;
}
if (other.tag == "Checkpoint")
{
respawnPosition = other.transform.position;
}
}
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "MovingPlatform")
{
transform.parent = other.transform;
}
}
void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.tag == "MovingPlatform")
{
transform.parent = null;
}
}
}
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;
public class LevelManager : MonoBehaviour {
public float waitToRespawn;
public PlayerController thePlayer;
public GameObject deathSplosion;
public int coinCount;
public Text coinText;
public Image heart1;
public Image heart2;
public Image heart3;
public Sprite heartFull;
public Sprite heartHalf;
public Sprite heartEmpty;
public int maxHealth;
public int healthCount;
private bool respawning;
public ResetOnRespawn[] objectsToReset;
public bool invincible;
public Text livesText;
public int startingLives;
public int currentLives;
// Use this for initialization
void Start () {
thePlayer = FindObjectOfType<PlayerController> ();
coinText.text = "Coins: " + coinCount;
healthCount = maxHealth;
objectsToReset = FindObjectsOfType<ResetOnRespawn>();
currentLives = startingLives;
livesText.text = "Lives x " + currentLives;
}
// Update is called once per frame
void Update () {
if (healthCount <= 0 )
{
Respawn ();
respawning = true;
}
}
public void Respawn()
{
if (!respawning) {
currentLives -= 1;
livesText.text = "Lives x " + currentLives;
if (currentLives > 0) {
respawning = true;
StartCoroutine ("RespawnCo");
} else {
thePlayer.gameObject.SetActive (false);
}
}
}
public IEnumerator RespawnCo()
{
thePlayer.gameObject.SetActive (false);
Instantiate (deathSplosion, thePlayer.transform.position, thePlayer.transform.rotation);
yield return new WaitForSeconds (waitToRespawn);
healthCount = maxHealth;
respawning = false;
UpdateHeartMeter ();
coinCount = 0;
coinText.text = "Coins: " + coinCount;
thePlayer.transform.position = thePlayer.respawnPosition;
thePlayer.gameObject.SetActive (true);
for (int i = 0; i < objectsToReset.Length; i++)
{
objectsToReset [i].gameObject.SetActive (true);
objectsToReset [i].ResetObject ();
}
}
public void AddCoins(int coinsToAdd)
{
coinCount += coinsToAdd;
coinText.text = "Coins: " + coinCount;
}
public void HurtPlayer(int damageToTake)
{
if (!invincible)
{
healthCount -= damageToTake;
UpdateHeartMeter ();
thePlayer.Knockback ();
}
}
public void UpdateHeartMeter()
{
switch (healthCount)
{
case 6:
heart1.sprite = heartFull;
heart2.sprite = heartFull;
heart3.sprite = heartFull;
return;
case 5:
heart1.sprite = heartFull;
heart2.sprite = heartFull;
heart3.sprite = heartHalf;
return;
case 4:
heart1.sprite = heartFull;
heart2.sprite = heartFull;
heart3.sprite = heartEmpty;
return;
case 3:
heart1.sprite = heartFull;
heart2.sprite = heartHalf;
heart3.sprite = heartEmpty;
return;
case 2:
heart1.sprite = heartFull;
heart2.sprite = heartEmpty;
heart3.sprite = heartEmpty;
return;
case 1:
heart1.sprite = heartHalf;
heart2.sprite = heartEmpty;
heart3.sprite = heartEmpty;
return;
case 0:
heart1.sprite = heartEmpty;
heart2.sprite = heartEmpty;
heart3.sprite = heartEmpty;
return;
default:
heart1.sprite = heartEmpty;
heart2.sprite = heartEmpty;
heart3.sprite = heartEmpty;
return;
}
}
}
I suspect it is because there is a ti$$anonymous$$g clash when you run your respawning co-routine. For example, you have respawning=true in your update routine and respawning=false in your co-routine. You also have a respawning=true in your Respawn routine. They are perhaps tripping each other up. I think tidy up your logic here. In your update routine, you only need to run Respawn() when the health=0 AND it is not currently respawning AND current lives are greater than 0. Then you don't need any tests in your Respawn routine as it can only ever be run when a respawn is required. Set respawning to true as soon as you call Respawn and set it to false when your co-routine ends.
Thanks for your reply david! Please can you tell me where I've to make these changes as I'm a beginner in coding. Thanks , Ishan
Answer by Runalotski · Aug 18, 2018 at 01:52 PM
HI,
As your hurt function can allow any amount of damage you can add a check to round the health back up to 0.
public void HurtPlayer(int damageToTake)
{
if (!invincible)
{
healthCount -= damageToTake;
//If health is now less than 0 make it 0
if(healthCount < 0)
healthCount = 0;
UpdateHeartMeter ();
thePlayer.Knockback ();
}
}
Hello @Runalotski . I've made the changes but nothing changed. It's the same 3,2,1,-1.