Hangman game

Hi everyone, its my first time writing here. I’m currently making a hangman game where it has categories and I’m using text asset for the puzzle thingy. I’m working on only one category since I could just copy and paste and modify the text asset anyway. Now my problem right now is that, in my game scene, it contains a back button and whenever I click on it, words from the text asset gets deleted. This also happens even if I haven’t answered properly or lose on purpose. However, I needed to delete the words from the text asset since whenever the player completes the puzzle category or loses, they will be directed to the scoring scene. I would appreciate if anyone would help me with this. Thank you in advance!

Here’s the game manager script:

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


public class GameManager : MonoBehaviour
{
    [SerializeField] GameObject wordContainer;
    [SerializeField] GameObject keyboardContainer;
    [SerializeField] GameObject letterContainer;
    [SerializeField] GameObject[] hangmanStages;
    [SerializeField] GameObject letterButton;
    [SerializeField] TextAsset possibleWord;
    [SerializeField] TextMeshProUGUI scoreText;

    public static GameManager Instance { get; private set; }

    private static List<string> possibleWordsList;

    private string word;
    public string funFact;
    public int correctGuesses, incorrectGuesses;
    public static int score = 0;

    private bool isGamePaused = false;


    // Start is called before the first frame update
    void Start()
    {
        if (possibleWordsList == null)
        {
            possibleWordsList = new List<string>(possibleWord.text.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries));
            ShuffleList(possibleWordsList);
        }

        InitialiseButtons();
        if (!isGamePaused)
        {
            InitialiseGame();
            UpdateScoreDisplay();
        }

    }


    private void InitialiseButtons()
    {
        for(int i = 65; i <= 90; i++)
        {
            CreateButton(i);
        }
    }

    private void InitialiseGame()
    {
        //Reset data back to original state
        incorrectGuesses = 0;
        correctGuesses = 0;


        foreach (Button child in keyboardContainer.GetComponentsInChildren<Button>())
        {
            child.interactable = true;
        }

        foreach(Transform child in wordContainer.GetComponentInChildren<Transform>())
        {
            Destroy(child.gameObject);
        }

        foreach(GameObject stage in hangmanStages)
        {
            stage.SetActive(true);
        }

        if (possibleWordsList.Count == 0)
        {
            SceneManager.LoadScene("Score");
            Debug.Log("No more words to guess. Game Over.");
            return;
        }

        //Generate new word
        word = possibleWordsList[0].ToUpper();
        Debug.Log($"Removing word '{word}' from the list.");
        possibleWordsList.RemoveAt(0);
        foreach (char letter in word)
        {
            var temp = Instantiate(letterContainer, wordContainer.transform);
        }
    }

    public string CurrentWord
    {
        get { return word; }
    }

    private void CreateButton(int i)
    {
        GameObject temp = Instantiate(letterButton, keyboardContainer.transform);
        temp.GetComponentInChildren<TextMeshProUGUI>().text = ((char)i).ToString();
        temp.GetComponent<Button>().onClick.AddListener(delegate { CheckLetter(((char)i).ToString()); });
    }

  

    private void CheckLetter(string inputLetter)
    {
        bool letterInWord = false;
        for(int i = 0; i < word.Length; i++)
        {
            if(inputLetter == word[i].ToString())
            {
                letterInWord = true;
                correctGuesses++;
                wordContainer.GetComponentsInChildren<TextMeshProUGUI>()[i].text = inputLetter;
            }
        }
        if(letterInWord == false)
        {
            incorrectGuesses++;
            hangmanStages[incorrectGuesses - 1].SetActive(false);
        }
        CheckOutcome();
    }


    private void CheckOutcome()
    {
        if(correctGuesses == word.Length) //Win
        {
            for(int i = 0; i < word.Length; i++)
            {
                wordContainer.GetComponentsInChildren<TextMeshProUGUI>()[i].color = Color.green;
            }


            FunFact.currentWord = word;

            FunFactScene();

            score += 10;
            UpdateScoreDisplay();

            //Invoke("InitialiseGame", 3f);
        }

        if(incorrectGuesses == hangmanStages.Length) //Lose
        {
            for(int i = 0; i < word.Length; i++)
            {
                wordContainer.GetComponentsInChildren<TextMeshProUGUI>()[i].color = Color.red;
                wordContainer.GetComponentsInChildren<TextMeshProUGUI>()[i].text = word[i].ToString();
            }
            Debug.Log("Game Over. You lost.");
            SceneManager.LoadScene("Score");
        }
    }

    private void ShuffleList<T>(List<T> list)
    {
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = UnityEngine.Random.Range(0, n + 1);
            T value = list[k];
            list[k] = list[n];
            list[n] = value;
        }
    }

    void UpdateScoreDisplay()
    {
        if (scoreText != null)
        {
            scoreText.text = "Score: " + score;
            PlayerPrefs.SetInt("SavedScore", score);
        }
    }


    private void FunFactScene()
    {
        isGamePaused = true;
        Time.timeScale = 0.0f;
        SceneManager.LoadScene("Fun Fact");
    }

    public void ResumeGame()
    {
        isGamePaused = false;
        Time.timeScale = 1.0f;
        InitialiseGame();
    }


}

If anyone have any questions regarding my game, feel free to ask.

To achieve this, you should separate the initialization of the game from deleting words in the text asset. Initialize the game only once at the start and then handle the back button and game over cases without modifying the words list. Let’s make some modifications to your code:

  1. Separate Initialization and Word Removal: We’ll remove the word removal logic from the Start() method and place it in a separate method called RemoveCurrentWordFromList(). This way, the words in the text asset won’t be deleted when the player goes back or loses the game.
  2. Handle Back Button: Modify the ResumeGame() method to handle the back button. When the back button is pressed, it should go back to the main menu or wherever you intend it to go, without deleting words.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;


public class GameManager : MonoBehaviour
{
    [SerializeField] GameObject wordContainer;
    [SerializeField] GameObject keyboardContainer;
    [SerializeField] GameObject letterContainer;
    [SerializeField] GameObject[] hangmanStages;
    [SerializeField] GameObject letterButton;
    [SerializeField] TextAsset possibleWord;
    [SerializeField] TextMeshProUGUI scoreText;

    public static GameManager Instance { get; private set; }

    private static List<string> possibleWordsList;

    private string word;
    public string funFact;
    public int correctGuesses, incorrectGuesses;
    public static int score = 0;

    private bool isGamePaused = false;

private void Start()
{
    if (possibleWordsList == null)
    {
        possibleWordsList = new List<string>(possibleWord.text.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries));
        ShuffleList(possibleWordsList);
    }

    InitialiseButtons();
    if (!isGamePaused)
    {
        InitialiseGame();
        UpdateScoreDisplay();
    }
}

private void InitialiseGame()
{
    // Reset data back to original state
    incorrectGuesses = 0;
    correctGuesses = 0;

    foreach (Button child in keyboardContainer.GetComponentsInChildren<Button>())
    {
        child.interactable = true;
    }

    foreach (Transform child in wordContainer.GetComponentInChildren<Transform>())
    {
        Destroy(child.gameObject);
    }

    foreach (GameObject stage in hangmanStages)
    {
        stage.SetActive(true);
    }

    if (possibleWordsList.Count == 0)
    {
        SceneManager.LoadScene("Score");
        Debug.Log("No more words to guess. Game Over.");
        return;
    }

    // Generate new word
    word = possibleWordsList[0].ToUpper();
    Debug.Log($"Removing word '{word}' from the list.");
    // Do not remove the word from the list here
    foreach (char letter in word)
    {
        var temp = Instantiate(letterContainer, wordContainer.transform);
    }
}

private void RemoveCurrentWordFromList()
{
    if (possibleWordsList.Count > 0)
    {
        Debug.Log($"Removing word '{word}' from the list.");
        possibleWordsList.RemoveAt(0);
    }
}

public void ResumeGame()
{
    // Add logic to handle back button (e.g., go back to main menu)
    SceneManager.LoadScene("MainMenu");
}

// ... (rest of your code)

private void CheckOutcome()
{
    if (correctGuesses == word.Length) // Win
    {
        // ... (existing code)

        // Remove the word only when the player wins
        RemoveCurrentWordFromList();
    }

    if (incorrectGuesses == hangmanStages.Length) // Lose
    {
        // ... (existing code)

        // Don't remove the word on losing
    }
}

// ... (existing code)