Can't get a script to read a public int. Please Help

My first goto is a race condition. Check if moving the ActivateSelectedShip() code out of Awake() and into Start() works.

1 Like

I should have said. I’ve tried it in awake, start, update, OnEnable, and pretender. None of it worked, all only pull a value of 0.

Sounds like you’re encountering a race condition when grabbing the first reference to GameSession inside your Player script.

Within Player.cs


Try Moving your gameSession = FindObjectOfType<GameSession>(); into Start().

1 Like

I’ve tried that too. Also tried to put it in update, also didn’t work.
I’ve also tried to put it within ActivateSelectedShip()

I am almost 100% sure you have a race condition. Go to the project settings and update the script execution order.

Click the + and add your GameSession. Then move it above the ‘Default Time’ bar.

1 Like

I would never of thought to look there. I’ll give it try tomorrow and report back.
Thank you.

It’s not something I usually recommend. There are other (better, imo) ways to fix race conditions but it’s not ‘incorrect’ to do it like this

Spent a few extra minutes just going through your code one line at a time. It appears you’ve got multiple integers you’re referencing but none of them are very clear what they’re trying to achieve.

GameSession


a global integer state shipPicked

  • This state isn’t being used within this script what so ever. It’s really not doing anything from having a glance at GameSession.cs unless some piece of UI logic is modifiying it within Unity. (Which your OP mentions something to that effect.)

Player


However, on your Player script you have

a global integer state playerShipPicked

  • Now inside your Awake method you’re debugging the GameSession shipPicked but again, unless UI is modifying it, it would return whatever you set it inside the inspector.

  • Maybe by accident, but inside your Start method you’re checking "Debug.Log("Player ship Picked " + playerShipPicked); Neither of these states have been modified at all according to these scripts at that particular point in time.


Importantly inside your method ActivateSelectShip()


You’ve declared a local integer ThisShip and assigned it to the GameSession’s shipPicked but again, no idea what exactly is supposed to be changing that state, or if your UI buttons are pointing to that specific one, and not the player playerShipPicked by mistake.

And then the significance of what actually gets selected is dependent on the shipPicked and not the playerShipPicked…

TLDR:
So maybe you need to check whether your UI logic is correctly referencing the integer from your GameSession and not your Player’s by accident.

Edit:


It appears your conditional statement can be another issue.

public void ActivateSelectedShip()
{
    Debug.Log("Activating Selected Ship");
    Debug.Log(playerShipPicked);
    int ThisShip = gameSession.shipPicked;
    if (playerShipPicked == 0)
    {
        Debug.Log("Ship 1 to go by default");
        ActivateShip1();
    }
    if (ThisShip == 1)
    {
        Debug.Log("Ship 1 to go");
        ActivateShip1();
    }
    else if (ThisShip == 2)
    {
        Debug.Log("Ship 2 to go");
        ActivateShip2();
    }
    else if (ThisShip == 3)
    {
        Debug.Log("Ship 3 to go");
        ActivateShip3();          
    }

}

Because playerShipPicked is always going to be 0 by default (granted you’re not modifying it outside of this script currently) then condition 0 is always chosen.

Maybe restructure the conditions by using

if (ThisShip == 0)

I also went through the code and with the code as it is currently, ship 2 will be picked because the shipPicked is defaulted to 2. OP did not say that it is always picking ship 2, so I assumed this is not the problem. I stripped out a bunch of the code I don’t care about and ran the code that I could. All this wrote a lot to console, but I could see that it is in fact (in my instance) selecting ship 2, but it never changes playerShipPicked because that value is never set to anything either

I tried changing the script order in Project settings, but didn’t work.

Now I’m finding another issue with something that DID work from GameSession in Player.cs, but no longer works, it only reads 0…
This way my particle weapon ammo. now no more.

If I disable ActivateSelectedShip() and enable a ship in the Hierarchy and run the game directly from the First Level Scene, it works again. BUT if I run the game from the ship selector, particle weapon doesn’t work any more, it keeps reading 0 value from GameSession.cs

It seems that my ship Selector scene, or ShipSelector.cs is messing with it… how? why?

I have a LootPickUp.cs also, which instantiates loot drops, I put a debug in a drop to see what it finds with ShipPicked, and it always reads out correctly…

I realized when I posted this I was tired and left a mess of trial and error in the scripts. I cleaned them up a bit. Here is ShipSelector too.

‘’’
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using TMPro;

public class GameSession : MonoBehaviour
{
[SerializeField] int basePlayerLives = 3;
[SerializeField] int score = 0;
[SerializeField] float deathDelay = 3f;
[SerializeField] TextMeshProUGUI LivesText;
[SerializeField] TextMeshProUGUI ScoreText;

ScoreKeeper scoreKeeper;
LevelManager levelManager;
LivesIcons livesIcons;
ShipSelector shipSelector;
Player player;

public Canvas Hud;

public int particleWeaponAmmo = 0;
public int playerLives = 3;
public int gunLevel;
public int speedLevel = 1;
public int shipPicked; // this is changed from ShipSelector.cs , it does change in inspector correctly.

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

    scoreKeeper = FindObjectOfType<ScoreKeeper>();
    shipSelector = FindObjectOfType<ShipSelector>();
}

private void Start()
{
    LivesText.text = playerLives.ToString();
    levelManager = FindObjectOfType<LevelManager>();
    Hud = GetComponentInChildren<Canvas>();
    livesIcons = FindObjectOfType<LivesIcons>();
    player = FindObjectOfType<Player>();

    int CurrentScene = SceneManager.GetActiveScene().buildIndex;
    if (CurrentScene <= 4)
    {
        Hud.enabled = false;
    }
    else if(CurrentScene >=5)
    {
        Hud.enabled = true;
    }
}


public void ProcessPlayerDeath()
{
    if (playerLives > 1)
    {
        Invoke("TakeLife", deathDelay);            
    }
    else
    {
        Invoke("ResetGameSession", deathDelay);            
    }
}

public void ProcessBossDeath()
{
    int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    int nextSceneIndex = currentSceneIndex + 1;

    if (nextSceneIndex == SceneManager.sceneCountInBuildSettings)
    {
        Invoke("FinishedGame", deathDelay);
    }
    else
    {
        levelManager.LoadNextLevel();
    }
}

public void GoBackToMenu()
{
    Invoke("BackToMenu", 0);
}
public void AddToScore(int pointsToAdd)
{
    score += pointsToAdd;
    ScoreText.text = score.ToString();
}

void TakeLife()
{
    playerLives--;
    livesIcons.ProcessPlayerLivesIcons();
    int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    SceneManager.LoadScene(currentSceneIndex);
    LivesText.text = playerLives.ToString();
}

void ResetGameSession()
{
    SceneManager.LoadScene("GameOver");
    ResetLives();        
    LivesText.text = playerLives.ToString();
    livesIcons.ProcessPlayerLivesIcons();
    Hud.enabled = false;
}

void FinishedGame()
{
    ResetLives();
    SceneManager.LoadScene("FinishedGame");
    LivesText.text = playerLives.ToString();
    Hud.enabled = false;
}

void BackToMenu()
{
    ResetLives();
    Time.timeScale = 1f;        
    SceneManager.LoadScene("MainMenu");
    Hud.enabled = false;
    LivesText.text = playerLives.ToString();        
}

void Update()
{
    ScoreText.text = scoreKeeper.GetScore().ToString("000000000");
}

public void ResetLives()
{
    playerLives = basePlayerLives;
    FindObjectOfType<GameSession>().gunLevel = 0;
}

public void ShipSelected() // this is called by "play button on shipselector UI"
{
    if(shipPicked == 1)
    {
        Debug.Log("Ship 1 Selected");
        levelManager.LoadFirstLevel();
        // player.ActivateShip1();  tried to put this here, but the script isn't active until new scene is loaded.
        return;
    }
    if (shipPicked == 2)
    {
        Debug.Log("Ship 2 Selected");
        levelManager.LoadFirstLevel();
        return;
    }
    if (shipPicked == 3)
    {
        Debug.Log("Ship 3 Selected");
        levelManager.LoadFirstLevel();
        return;
    }

}

}
‘’’

PLAYER.CS
‘’’
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
public float moveSpeed = 10f;
Vector2 rawInput;

[SerializeField] float paddingLeft;
[SerializeField] float paddingRight;
[SerializeField] float paddingTop;
[SerializeField] float paddingBottom;
[SerializeField] ParticleSystem particleWeaponParticles;
[SerializeField] AudioClip particleWeaponSFX;

// children under Player, by default each is deactivated.
[SerializeField] GameObject ship1;
[SerializeField] GameObject ship2;
[SerializeField] GameObject ship3;

[SerializeField] GameSession gameSession;  //This fixed my issue

[SerializeField] UnityEngine.GameObject pauseMenuUI;
public static bool GameIsPaused = false;

GunLevel gunLevel;
SpeedLevel speedLevel;
PWeaponAmmoIcons pWeaponAmmoIcons;
LevelManager levelManager;

Vector2 minBounds;
Vector2 maxBounds;

Shooter shooter;
Gun[] guns;

AudioPlayer audioPlayer;
//GameSession gameSession;

bool isFiring;

private void Awake()
{
    gameSession = FindObjectOfType<GameSession>();
    
    levelManager = FindObjectOfType<LevelManager>();
    Debug.Log("Player.cs Awake ship picked " + gameSession.shipPicked); //always reads as 0 on console
}

private void Start()
{
    InitBounds();
    shooter = GetComponent<Shooter>();
    guns = transform.GetComponentsInChildren<Gun>();
    gunLevel = FindObjectOfType<GunLevel>();
    speedLevel = FindObjectOfType<SpeedLevel>();
    pWeaponAmmoIcons = FindObjectOfType<PWeaponAmmoIcons>();
    audioPlayer = FindObjectOfType<AudioPlayer>();

    ActivateSelectedShip();

    Debug.Log("Player.cs Start ship picked " + gameSession.shipPicked);   //this reads out on console, but only the value of 0
}

void Update()
{
    Move();
    guns = transform.GetComponentsInChildren<Gun>();
    Debug.Log("Player.cs Ship picked Update " + gameSession.shipPicked); // always reads 0..
}

void InitBounds()
{
    Camera mainCamera = Camera.main;
    minBounds = mainCamera.ViewportToWorldPoint(new Vector2(0, 0));
    maxBounds = mainCamera.ViewportToWorldPoint(new Vector2(1, 1));
}

private void Move()
{
    Vector3 delta = rawInput * moveSpeed * Time.deltaTime;
    Vector2 newPos = new Vector2();
    newPos.x = Mathf.Clamp(transform.position.x + delta.x, minBounds.x + paddingLeft, maxBounds.x - paddingRight);
    newPos.y = Mathf.Clamp(transform.position.y + delta.y, minBounds.y + paddingBottom, maxBounds.y - paddingTop);
    transform.position = newPos;
}

void OnMove(InputValue value)
{
    rawInput = value.Get<Vector2>();
}

void OnTriggerEnter2D(Collider2D other)
{
    if (other.tag == "SpeedBoost")
    {
        Debug.Log("Boost it!");
        Debug.Log("Player.cs OnTriggerEnter SpeedBoost ship picked " + gameSession.shipPicked); // returns value of 0
        speedLevel.ProcessSpeedLevel();
        Destroy(other.gameObject);
    }

    if (other.tag == "FireRateUp")
    {
        Debug.Log("Blast 'Em!!!");
        gunLevel.ProcessGunLevel();
        Destroy(other.gameObject);
    }
}
    void OnFire(InputValue value)
{       
    if (guns != null)
    {
        foreach (Gun gun in guns)
        {
            gun.isFiring = value.isPressed;                
        }
    }
    Debug.Log("Firing");
}

void OnFire2(InputValue value)
{
    Debug.Log("Particle Weapon Button Pressed");
    if (gameSession.particleWeaponAmmo >= 1) // this WAS working fine, now only reads value of 0. 
    {
        Debug.Log("Firing Super Weapon");
        gameSession.particleWeaponAmmo--;            
        Instantiate(particleWeaponParticles, transform.position, Quaternion.identity);
        audioPlayer.PlayParticleWeaponClip();
        Debug.Log("Particle Weapon Ammo: " + gameSession);
        pWeaponAmmoIcons.ProcessPWeaponAmmo();
    }
    
    Debug.Log("No Particle Weapon Ammo Left");
    return;
}

   void OnPause()
{
    Debug.Log("Pause");
    if (GameIsPaused)
    {
        Resume();
        Debug.Log("Resuming");
    }
    else
    {
        Pause();
        Debug.Log("Pausing");
    }
}

public void Resume()
{
    Debug.Log("Resume???");
    pauseMenuUI.SetActive(false);
    Time.timeScale = 1f;
    GameIsPaused = false;
}

public void Pause()
{
    pauseMenuUI.SetActive(true);
    Time.timeScale = 0f;
    GameIsPaused = true;
}

public void ActivateSelectedShip()
{
    
    Debug.Log("Activating Selected Ship"); // this reads out on console
    Debug.Log("ActivateSelectedShip() ship picked " + gameSession.shipPicked); //this only reads out on console with value of 0
    if (gameSession.shipPicked == 0) // this works, but only because it can't seem to find any value other than 0, even though in inspector it is different.
    {
        Debug.Log("Ship 1 to go by default");
        ActivateShip1();
    }
    if (gameSession.shipPicked == 1)
    {
        Debug.Log("Ship 1 to go");
        ActivateShip1();
    }
    else if (gameSession.shipPicked == 2)
    {
        Debug.Log("Ship 2 to go");
        ActivateShip2();
    }
    else if (gameSession.shipPicked == 3)
    {
        Debug.Log("Ship 3 to go");
        ActivateShip3();          
    }

}
public void ActivateShip1()
{
    ship1.gameObject.SetActive(true);
    Debug.Log("Ship 1 should work now..?");
    ship2.gameObject.SetActive(false);
    ship3.gameObject.SetActive(false);
    return;
}

public void ActivateShip2()
{
    ship1.gameObject.SetActive(false);
    ship2.gameObject.SetActive(true);
    Debug.Log("Ship 2 should work now..?");
    ship3.gameObject.SetActive(false);
    return;
}

public void ActivateShip3()
{
    ship1.gameObject.SetActive(false);
    ship2.gameObject.SetActive(false);
    ship3.gameObject.SetActive(true);
    Debug.Log("Ship 3 should work now..?");
    return;
}

}

‘’’

SHIPSELECTOR.CS
‘’’
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class ShipSelector : MonoBehaviour
{
// these are just the info sheets on the ships for the UI
[SerializeField] GameObject ship1Info;
[SerializeField] GameObject ship2Info;
[SerializeField] GameObject ship3Info;

GameSession gameSession;

void Start()
{
    
}

void Update()
{
    gameSession = FindObjectOfType<GameSession>();
}

public void SelectShip1()
{
    gameSession.shipPicked = 1;
    ship1Info.gameObject.SetActive(true);
    ship2Info.gameObject.SetActive(false);  
    ship3Info.gameObject.SetActive(false);
}
public void SelectShip2()
{
    gameSession.shipPicked = 2;
    ship1Info.gameObject.SetActive(false);
    ship2Info.gameObject.SetActive(true);
    ship3Info.gameObject.SetActive(false);
}
public void SelectShip3()
{
    gameSession.shipPicked = 3;
    ship1Info.gameObject.SetActive(false);
    ship2Info.gameObject.SetActive(false);
    ship3Info.gameObject.SetActive(true);
}

}
‘’’

@bixarrio @Brandon_Richards

I found a fix for the issue, I just put a {Serializefield] GamesSession gameSession; and added the script in each level.

I would still like to know if there was another solution to this, it seems weird that ShipSelector.cs seemed to break Player.cs… I want to know what I did wrong, so I can maybe avoid it in the future.

I thank you both for helping me out here! It’s good to have a community with people so willing to help.

This makes even less sense, now. The script you dragged into the inspector would be destroyed as soon as the level loads because the reference is the second instance of GameSession and your ‘singleton’ code would destroy it. Fortunately the Awake code replaces whatever you dragged in there (even if it didn’t get destroyed) with the original game session. Why it would suddenly work in this case is really, really confusing. All of this is essentially still doing the same thing as before.

If you really want, you could zip and drop the project somewhere and I could look into it. I kinda want to get down to the bottom of this. It really doesn’t make sense. I’m missing something somewhere and it irritates me.

2 Likes

Hey, hope you don’t mind.

Spent about 20 minutes, just cleaned up some of your scripts for you. This way Debugging should be a little bit easier in the future.

(Granted no pressure about using the scripts… can be used as a reference perhaps. I only changed what I knew wouldn’t break anything as a resort of changes.)

Player.cs


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

public class Player : MonoBehaviour
{
    // CONFIGURABLE PARAMETERS
    [SerializeField] float moveSpeed = 10f;
    [SerializeField] float paddingLeft;
    [SerializeField] float paddingRight;
    [SerializeField] float paddingTop;
    [SerializeField] float paddingBottom;
    [SerializeField] ParticleSystem particleWeaponParticles;
    [SerializeField] AudioClip particleWeaponSFX;
    [SerializeField] GameObject[] playerShips; // <- Populate ships into the array
    [SerializeField] GameSession gameSession;
    [SerializeField] GameObject pauseMenuUI;


    // CACHED REFERENCES
    GunLevel gunLevel;
    SpeedLevel speedLevel;
    PWeaponAmmoIcons pWeaponAmmoIcons;
    LevelManager levelManager;
    AudioPlayer audioPlayer;
    Shooter shooter;

    // BOUNDARIES
    Vector2 minBounds;
    Vector2 maxBounds;

    // STATE
    Vector2 rawInput;
    Gun[] guns;


    // STATIC STATE
    public static bool GameIsPaused = false; // <- Maybe no longer needed?


    // PUBLIC

    public float GetMoveSpeed() => moveSpeed;

    public void ActivateSelectedShip()
    {
        Debug.Log("Activating Selected Ship");

        if (gameSession.GetSelectedShip() == 0 || gameSession.GetSelectedShip() == 1) EnableSelectedShip(playerShips[0]);
        else if (gameSession.GetSelectedShip() == 2) EnableSelectedShip(playerShips[1]);
        else EnableSelectedShip(playerShips[2]);

        Debug.Log($"ActivateSelectedShip() ship picked: {gameSession.GetSelectedShip()}");
    }

    // PRIVATE

    // Should get into a habit of caching things inside of Awake when able.
    // If something does break due to this - simply place it back into your Start().
    void Awake()
    {
        gameSession = FindObjectOfType<GameSession>();
        shooter = GetComponent<Shooter>();
        guns = transform.GetComponentsInChildren<Gun>();
        gunLevel = FindObjectOfType<GunLevel>();
        speedLevel = FindObjectOfType<SpeedLevel>();
        pWeaponAmmoIcons = FindObjectOfType<PWeaponAmmoIcons>();
        audioPlayer = FindObjectOfType<AudioPlayer>();
        levelManager = FindObjectOfType<LevelManager>();
    }

    void Start()
    {
        InitBounds();
        ActivateSelectedShip();
        Debug.Log($"Start: Ship Selected: {gameSession.GetSelectedShip()}");
    }

    void Update()
    {
        Move();
        guns = transform.GetComponentsInChildren<Gun>(); // <- Highly recommend caching and updating when you acquire new weapons.
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("SpeedBoost"))
        {
            Debug.Log("Boost it!");
            Debug.Log($"OnTriggerEnter SpeedBoost for Ship: { gameSession.GetSelectedShip()}");
            speedLevel.ProcessSpeedLevel();
            Destroy(other.gameObject);
        }

        if (other.CompareTag("FireRateUp"))
        {
            Debug.Log("Blast 'Em!!!");
            gunLevel.ProcessGunLevel();
            Destroy(other.gameObject);
        }
    }


    /// <summary>
    /// Enables a ship depending on which 'SelectShipX' was used. Deactivates any remaining ships.
    /// </summary>
    /// <param name="shipGO"></param>
    void EnableSelectedShip(GameObject shipGO)
    {
        foreach (GameObject ship in playerShips)
        {
            ship.SetActive(ReferenceEquals(shipGO, ship));
        }
    }

    void InitBounds()
    {
        Camera mainCamera = Camera.main;
        minBounds = mainCamera.ViewportToWorldPoint(new Vector2(0, 0));
        maxBounds = mainCamera.ViewportToWorldPoint(new Vector2(1, 1));
    }

    void Move()
    {
        Vector3 delta = rawInput * moveSpeed * Time.deltaTime;
        Vector2 newPos = new Vector2();
        newPos.x = Mathf.Clamp(transform.position.x + delta.x, minBounds.x + paddingLeft, maxBounds.x - paddingRight);
        newPos.y = Mathf.Clamp(transform.position.y + delta.y, minBounds.y + paddingBottom, maxBounds.y - paddingTop);
        transform.position = newPos;
    }

    #region InputSystem

    void OnMove(InputValue value) => rawInput = value.Get<Vector2>();

    void OnFire(InputValue value)
    {
        if (guns != null)
        {
            foreach (Gun gun in guns)
            {
                gun.isFiring = value.isPressed;
            }
        }
        Debug.Log("Firing");
    }

    void OnFire2(InputValue value)
    {
        Debug.Log("Particle Weapon Button Pressed");

        if (gameSession.GetParticleWeaponAmmo() >= 1)
        {
            gameSession.DecrementAmmo();
            Instantiate(particleWeaponParticles, transform.position, Quaternion.identity);
            audioPlayer.PlayParticleWeaponClip();
            Debug.Log($"Particle Weapon Ammo: {gameSession.GetParticleWeaponAmmo()}");
            pWeaponAmmoIcons.ProcessPWeaponAmmo();
        }

        Debug.Log("No Particle Weapon Ammo Left");
        return;
    }
    #endregion

    float IsGamePaused() => pauseMenuUI.activeSelf ? Time.timeScale = 0 : Time.timeScale = 1;

    void Resume()
    {
        Debug.Log("Game Resumed");
        pauseMenuUI.SetActive(false);
        GameIsPaused = false; // <- Probably no longer needed?
        IsGamePaused();
    }

    void Pause()
    {
        Debug.Log("Game Paused");
        pauseMenuUI.SetActive(true);
        GameIsPaused = true; // <- Probably no longer needed?
        IsGamePaused();
    }
}

GameSession.cs


using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;

public class GameSession : MonoBehaviour
{
    // CONFIGURABLE PARAMETERS
    [SerializeField] Canvas Hud;
    [SerializeField] int basePlayerLives = 3;
    [SerializeField] int playerLives = 3;
    [SerializeField] int particleWeaponAmmo = 0;
    [SerializeField] int score = 0;
    [SerializeField] float deathDelay = 3f;
    [SerializeField] TextMeshProUGUI LivesText;
    [SerializeField] TextMeshProUGUI ScoreText;

    // CACHED REFERENCES
    ScoreKeeper scoreKeeper;
    LevelManager levelManager;
    LivesIcons livesIcons;
    ShipSelector shipSelector;
    Player player;

    // PRIVATE STATE
    int speedLevel = 1;
    int shipPicked;
    int gunLevel;

    // PUBLIC

    #region GETTERS & SETTERS

    public Canvas GetHUD() => Hud;
    public int GetParticleWeaponAmmo() => particleWeaponAmmo;
    public void SetParticleWeaponAmmo(int particleWeaponAmmo) => this.particleWeaponAmmo = particleWeaponAmmo;
    public int GetPlayerLives() => playerLives;
    public void SetPlayerLives(int playerLives) => this.playerLives = playerLives;
    public int GetSpeedLevel() => speedLevel;
    public void SetSpeedLevel(int speedLevel) => this.speedLevel = speedLevel;
    public int GetSelectedShip()
    {
        if (shipPicked == 1) return 1;
        else if (shipPicked == 2) return 2;
        return 3;
    }
    public void SetSelectedShip(int shipPicked) => this.shipPicked = shipPicked;
    #endregion

    public int DecrementAmmo() => particleWeaponAmmo > 0 ? particleWeaponAmmo-- : 0;

    public void ShipSelected()
    {
        Debug.Log($"{GetSelectedShip()} was selected! \nNow loading into the First Level...");
        levelManager.LoadFirstLevel();
    }

    public void AddToScore(int pointsToAdd)
    {
        score += pointsToAdd;
        ScoreText.text = score.ToString();
    }


    public void GoBackToMenu()
    {
        Invoke("BackToMenu", 0);
    }

    public void ProcessPlayerDeath()
    {
        if (GetPlayerLives() > 1)
        {
            Invoke("TakeLife", deathDelay);
        }
        else
        {
            Invoke("ResetGameSession", deathDelay);
        }
    }

    public void ProcessBossDeath()
    {
        if ((GetActiveScene() + 1) == SceneManager.sceneCountInBuildSettings)
        {
            Invoke("FinishedGame", deathDelay);
        }
        else
        {
            levelManager.LoadNextLevel();
        }
    }

    public void ResetLives()
    {
        playerLives = basePlayerLives;
        gunLevel = 0;
        DisplayPlayerLivesText();
        Hud.enabled = false;
    }


    // PRIVATE

    int GetActiveScene() => SceneManager.GetActiveScene().buildIndex;

    void DisplayPlayerLivesText() => LivesText.text = GetPlayerLives().ToString();

    bool EnableHeadsupDisplay()
    {
        if (GetActiveScene() <= 4) return false;
        return true;
    }

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

        scoreKeeper = FindObjectOfType<ScoreKeeper>();
        shipSelector = FindObjectOfType<ShipSelector>();
        levelManager = FindObjectOfType<LevelManager>();
        Hud = GetComponentInChildren<Canvas>();
        livesIcons = FindObjectOfType<LivesIcons>();
        player = FindObjectOfType<Player>();
    }

    void Start()
    {
        DisplayPlayerLivesText();
        Hud.enabled = EnableHeadsupDisplay();
    }

    void Update() => ScoreText.text = scoreKeeper.GetScore().ToString("000000000");
    

    void TakeLife()
    {
        playerLives--;
        livesIcons.ProcessPlayerLivesIcons();
        SceneManager.LoadScene(GetActiveScene());
        DisplayPlayerLivesText();
    }

    void ResetGameSession()
    {
        SceneManager.LoadScene("GameOver");
        ResetLives();
        livesIcons.ProcessPlayerLivesIcons();
    }

    void FinishedGame()
    {
        ResetLives();
        SceneManager.LoadScene("FinishedGame");
    }

    void BackToMenu()
    {
        ResetLives();
        Time.timeScale = 1f;
        SceneManager.LoadScene("MainMenu");
    }
}

ShipSelector.cs


using UnityEngine;

/// <summary>
/// Slot in your Ship GameObjects into the ships array.
/// </summary>
public class ShipSelector : MonoBehaviour
{
    // CONFIGURABLE PARAMETERS
    [SerializeField] GameObject[] ships;

    // CACHED REFERENCE
    GameSession gameSession;

    // PUBLIC

    public void SelectShip1()
    {
        gameSession.SetSelectedShip(1);
        EnableSelectedShip(ships[0]);
    }

    public void SelectShip2()
    {
        gameSession.SetSelectedShip(2);
        EnableSelectedShip(ships[1]);
    }

    public void SelectShip3()
    {
        gameSession.SetSelectedShip(3);
        EnableSelectedShip(ships[2]);
    }

    // PRIVATE

    void Awake() => gameSession = FindObjectOfType<GameSession>();

    /// <summary>
    /// Enables a ship depending on which 'SelectShipX' was used. Deactivates any remaining ships.
    /// </summary>
    /// <param name="shipGO"></param>
    void EnableSelectedShip(GameObject shipGO)
    {
        foreach (GameObject ship in ships)
        {
            ship.SetActive(ReferenceEquals(shipGO, ship));
        }
    }
}

Let me know how it goes.

1 Like

I get that, I’m happy it’s working, but not sure why, lol.
I figure it’ll come back to haunt me later, and besides, I’m trying to learn, so knowing WHY something works is important to me.
I can do that later tonight, I’ll PM you a link when it’s done.

Hey, I certainly do not mind!

Thank you!
I know my code needs a ton of work and cleaning up, you don’t want to see the rest of it, you’d get whiplash form the amount of head shaking and face palms you’d do.

I will go though this and try an implement as much as I can, trying to learn as I go.

Thanks again!

Hi @LongTooth,

I’m glad bixarrio and Brandon helped you with this problem. Is it solved now? :slight_smile:


See also:

1 Like

It’s working, but I feel it’s not solved yet. I’ll post a solution when it’s sorted though.

Yep. If we don’t learn the lessons of history, we’re doomed to repeat them.

After a brief look over, I also think you created a race condition.

1 Like

I looked at the project and couldn’t replicate the issue. The new code and the OP code all did what was expected. I’m not sure what happened originally.

image

1 Like

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

Privacy & Terms