UnityWebRequest issue

I am running into a little odd issue while using UnityWebRequest.

I have a button that when clicked checks my mysql database and gets all of my characters assigned to may account into an array. This all works fine. I then use that array to make some changes to a character select menu, where I have 10 buttons, one for each character a person can make. I am trying to get the buttons to update according to the number of characters an account has. In my explanation below I will make it easy and say the account has 2 characters.

I have it so that the first button gets the name of the first character, the second button gets the name of the second character, if there are no more characters in the array the rest of the buttons have their text component set to “Create Character”

When I go to the character select window, everything works fine. I see the buttons all named accordingly and their onclick events work fine. However, my issue starts when I add another character. I then go back to the character select screen and the buttons are all named correctly, but their onclick events seem to get messed up. A button that once said Create Character and had an onclick to go to create a new character, properly has a character name on it, however instead of taking me to the character it’s onlick still takes me to the create character screen. Also, the debug.log will display the last character the account has, no matter what button I click. if I click button 1 that should say First Character, it actually prints out Last Character in the list, very odd. I believe my issue is somehow due to the use of the co routine loop etc. I have tried stopping the co routine and starting it again, etc. If I log out of the account and then back in, when I go to the character select screen it all works, until I create another character, then I have to log out and log back in for the buttons to all work properly. Any help is greatly appreciated. Sorry for the long book here, but wanted to try to provide what I could.

First off I am by no means a great programmer so I know my code sucks, but here is my populateCharacters script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;

public class PopulateCharacters : MonoBehaviour
{
    public Button char1;
    public Button char2;
    public Button char3;
    public Button char4;
    public Button char5;
    public Button char6;
    public Button char7;
    public Button char8;
    public Button char9;
    public Button char10;

    public Canvas createCharacterCanvas;
    public Canvas selectCharacterCanvas;

    // Start is called before the first frame update
    public void populateCharacters()
    {
        StartCoroutine(populateTheCharacters());
    }

    IEnumerator populateTheCharacters()
    {
        WWWForm form = new WWWForm();
        form.AddField("player_id", DBManager.Player_ID);

        Debug.Log("Sending player id to DB Query: " + DBManager.Player_ID);

        UnityWebRequest webRequest = UnityWebRequest.Post("http://localhost/multiplayer_003/character_select.php", form);
        yield return webRequest.SendWebRequest();
        
        string[] webResults = webRequest.downloadHandler.text.Split('	');

        List<string> myCharacters = new List<string> { };
        List<Button> myButtons = new List<Button> { };
        myButtons.Add(char1);
        myButtons.Add(char2);
        myButtons.Add(char3);
        myButtons.Add(char4);
        myButtons.Add(char5);
        myButtons.Add(char6);
        myButtons.Add(char7);
        myButtons.Add(char8);
        myButtons.Add(char9);
        myButtons.Add(char10);
        
        if (webResults.Length > 0 )
        {
            int num = 0;

            if (webResults[0] != "none")
            {
                foreach (string s in webResults)
                {
                    myCharacters.Add(s);
                }

                Debug.Log(myCharacters.Count);

                while (num < myCharacters.Count)
                {
                    Debug.Log(myCharacters[num] + " num is: " + num);

                    myButtons[num].GetComponentInChildren<Text>().text = myCharacters[num];
                    string theCharacterName = myButtons[num].GetComponentInChildren<Text>().text.ToString();
                    myButtons[num].onClick.AddListener
                        (
                            delegate
                            {
                                TaskPlayTheCharacter(theCharacterName);
                            }
                        );

                    num++;
                }

                while (num < 10)
                {
                    myButtons[num].GetComponentInChildren<Text>().text = "Create Character";
                    myButtons[num].onClick.AddListener
                        (
                            delegate
                            {
                                openCreateCharacterCanvas();
                            }
                        );

                    num++;
                }
            }
        }

    }

    void openCreateCharacterCanvas()
    {
        createCharacterCanvas.enabled = true;
        selectCharacterCanvas.enabled = false;
    }

    void TaskPlayTheCharacter(string charName)
    {
        Debug.Log("Playing the character: " + charName);
    }

}

Ok it looks like I was able to get it functioning. I’m not very happy with how I had to do it, but it seems to do what I need. I think garbage collection is horrible with this script, but…for now it will suffice.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;


public class PopulateCharacters : MonoBehaviour
{
    public Button char1;
    public Button char2;
    public Button char3;
    public Button char4;
    public Button char5;
    public Button char6;
    public Button char7;
    public Button char8;
    public Button char9;
    public Button char10;

    public Canvas createCharacterCanvas;
    public Canvas selectCharacterCanvas;

    public IEnumerator myCoroutine;

    public List<string> myCharacters;
    public List<Button> myButtons;

    public int destroycount;
    public UnityWebRequest webRequest;
    public string[] webResults;

    public string isRunning;

    public void populateCharacters()
    {
        myCoroutine = populateTheCharacters(0);
        StartCoroutine(myCoroutine);
    }

    public void stopTheCoroutine()
    {
        Debug.Log("Stopping myCourtine");
        StopCoroutine(myCoroutine);
    }

    IEnumerator populateTheCharacters(int number)
    {
        myCharacters = new List<string> { };
        myButtons = new List<Button> { };
        destroycount = 0;

        WWWForm form = new WWWForm();
        form.AddField("player_id", DBManager.Player_ID);

        webRequest = UnityWebRequest.Post("http://localhost/multiplayer_003/character_select.php", form);

        yield return webRequest.SendWebRequest();
    
        webResults = webRequest.downloadHandler.text.Split('	');

        myButtons.Add(char1);
        myButtons.Add(char2);
        myButtons.Add(char3);
        myButtons.Add(char4);
        myButtons.Add(char5);
        myButtons.Add(char6);
        myButtons.Add(char7);
        myButtons.Add(char8);
        myButtons.Add(char9);
        myButtons.Add(char10);
        
        if (webResults.Length > 0 )
        {
            if (webResults[0] != "none")
            {
                foreach (string s in webResults)
                {
                    myCharacters.Add(s);
                }

                Debug.Log(myCharacters.Count);

                while(destroycount < 10)
                {
                    Debug.Log("Removing all listeners");
                    Debug.Log("Removing all button text");
                    myButtons[destroycount].GetComponentInChildren<Text>().text = "Create Character";
                    myButtons[destroycount].onClick.RemoveAllListeners();
                    destroycount++;
                }

                while (number < myCharacters.Count)
                {
                     Debug.Log(myCharacters[number] + " num is: " + number);

                     myButtons[number].GetComponentInChildren<Text>().text = myCharacters[number];
                    
                    string theCharacterName = myButtons[number].GetComponentInChildren<Text>().text.ToString();
                    
                    myButtons[number].onClick.AddListener
                    (
                        delegate
                        {
                            TaskPlayTheCharacter(theCharacterName);
                        }
                    );

                    number++;
                }

                while (number < 10)
                {
                    myButtons[number].GetComponentInChildren<Text>().text = "Create Character";
                    myButtons[number].onClick.AddListener
                    (
                        delegate
                        {
                            openCreateCharacterCanvas();
                        }
                );

                    number++;
                }
            }
        }
        Debug.Log("Stopping coroutine");
        StopCoroutine(myCoroutine);
    }

    void openCreateCharacterCanvas()
    {
        createCharacterCanvas.enabled = true;
        selectCharacterCanvas.enabled = false;
    }

    void TaskPlayTheCharacter(string charName)
    {
        Debug.Log("Playing the character: " + charName);
    }

}

You really do not need to do all this staff inside a coroutine. Coroutine should only be used to wait for the response from the server. For example:

    IEnumerator PopulateTheCharacters(WWWForm form, System.Action<string> callback)
    {
        var webRequest = UnityWebRequest.Post("http://localhost/multiplayer_003/character_select.php", form);
        yield return webRequest.SendWebRequest();
        callback?.Invoke(webRequest.downloadHandler.text);
    }

    void DoStaff()
    {
        WWWForm form = new WWWForm();
        form.AddField("player_id", "some id");

        StartCoroutine(PopulateTheCharacters(form, response =>
        {
            var webResults = response.Split('	');

            // Do pther staff
        }));
    }