Lives Not Subtracting

Lives are not subtractiing in next level after completing current level.
If you proceed with 2 levels from current level then in next next level they will remain 2.

My GameSession code:-

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameSession : MonoBehaviour
{
    [SerializeField] int playerLives = 3;

    void Awake()
    {
        int numberOfGameSessions = FindObjectsOfType<GameSession>().Length;
        if(numberOfGameSessions > 1)
        {
            Destroy(gameObject);
        }
        else
        {
            DontDestroyOnLoad(gameObject);
        }
    }

    public void ProcessPlayerDeath()
    {
        if(playerLives > 0)
        {
            TakeLife();
        }
        else
        {
            ResetGame();
        }
    }

    void TakeLife()
    {
        playerLives--;
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

    void ResetGame()
    {
        SceneManager.LoadScene(0);
        Destroy(gameObject);
    }
}

My PlayerMovement code:-

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMovement : MonoBehaviour
{
    Vector2 moveInput;
    bool isPlayerRunning;
    bool isPlayerClimbing;
    bool isTouchingLayers;
    bool isPlayerAlive = true;

    Rigidbody2D playerRigidbody;
    Animator playerAnimator;
    CapsuleCollider2D playerBodyCollider;
    BoxCollider2D playerFeetCollider;
    // SpriteRenderer playerSpriteRenderer;
    GameSession gameSession;

    [SerializeField] float playerMoveSpeed = 2f;
    [SerializeField] float playerJumpSpeed = 5f;
    [SerializeField] float playerClimbSpeed = 3f;
    [SerializeField] Vector2 deathblow = new Vector2(4f, 4f);
    [SerializeField] GameObject arrow;
    // [SerializeField] Color32 playerDeathColor;
    [SerializeField] Transform bowPosition;
    float playerStartingGravity;

    void Start()
    {
        playerRigidbody = GetComponent<Rigidbody2D>();
        playerAnimator = GetComponent<Animator>();
        playerBodyCollider = GetComponent<CapsuleCollider2D>();
        playerFeetCollider = GetComponent<BoxCollider2D>();
        // playerSpriteRenderer = GetComponent<SpriteRenderer>();
        playerStartingGravity = playerRigidbody.gravityScale;
        gameSession = FindObjectOfType<GameSession>();
    }

    void Update()
    {
        isPlayerRunning = Mathf.Abs(moveInput.x) > Mathf.Epsilon;
        isPlayerClimbing = Mathf.Abs(moveInput.y) > Mathf.Epsilon;

        if(!isPlayerAlive) { return; }

        FlipPlayer();
        Run();
        ClimbLadder();
        Die();
    }

    void OnMove(InputValue value)
    {
        moveInput = value.Get<Vector2>();
        Debug.Log("Player moving...");
    }

    void OnJump(InputValue value)
    {
        if(isPlayerAlive)
        {
            if(value.isPressed && playerFeetCollider.IsTouchingLayers(LayerMask.GetMask("Ground")))
            {
                playerRigidbody.velocity += new Vector2(0f, playerJumpSpeed);
            }
        }
    }

    void FlipPlayer()
    {
        if(isPlayerRunning)
        {
            transform.localScale = new Vector2(Mathf.Sign(moveInput.x), 1f);
        }
    }

    void Run()
    {
        playerAnimator.SetBool("isRunning", isPlayerRunning);
        Vector2 playerMoveVelocity = new Vector2(moveInput.x * playerMoveSpeed, playerRigidbody.velocity.y);
        playerRigidbody.velocity = playerMoveVelocity;
    }

    void ClimbLadder()
    {
        if(playerBodyCollider.IsTouchingLayers(LayerMask.GetMask("Climbs")))
        {
            playerAnimator.SetBool("isClimbing", isPlayerClimbing);
            playerRigidbody.gravityScale = 0;
            Vector2 playerClimbVelocity = new Vector2(playerRigidbody.velocity.x, moveInput.y * playerClimbSpeed);
            playerRigidbody.velocity = playerClimbVelocity;
        }
        else
        {
            playerAnimator.SetBool("isClimbing", false);
            playerRigidbody.gravityScale = playerStartingGravity;
        }
    }

    void OnFire(InputValue value)
    {
        if(isPlayerAlive)
        {
            Instantiate(arrow, bowPosition.position, transform.rotation);
        }
    }

    void Die()
    {
        if(playerBodyCollider.IsTouchingLayers(LayerMask.GetMask("Enemies", "Hazards")))
        {
            isPlayerAlive = false;
            playerAnimator.SetTrigger("Dying");
            playerRigidbody.velocity = deathblow;
            // playerSpriteRenderer.color = playerDeathColor;
            gameSession.ProcessPlayerDeath();
        }
    }
}

Another student have also posted same question but there is no solution.

2 Likes

Hi,

Are there any error messages in your console in level 2? Maybe a NullReferenceException error?

Try this:

if(numberOfGameSessions > 1)
        {
            gameObject.SetActive(false); // <--- THIS
            Destroy(gameObject);
        }

Did this fix it?


See also:

2 Likes

This solves the problem.

This means that there were 2 GameSession objects for a few seconds which were causing the problem??

2 Likes

Yes, that’s what it meant. Destroy() does not destroy immediately but at the end of the frame. Other game objects could still find this active object and reference it. And when this object gets finally destroyed, you get a NullReferenceException error.

3 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms