Populating a list

Hi guys. Okay so the one area that really throws me off is how to populate a list. Currently I have a list that I need to populate when a player selects a series of letters. Lets say the letters selected are “t,h,i,s”. What I need to happen is that each object selected is populated into the list according to the order it is selected. Now this is where I hit the brick wall. If I make the list a plain up Array, it populates the array with the currently selected value, and then replaces it all with the next currently selected value. If I make it a list, I get nothing.

Here is the code:

void ScreenMouseRay() {   

        Vector3 mousePosition = Input.mousePosition;
        mousePosition.z = 10f;
       
        Vector2 v = Camera.main.ScreenToWorldPoint(mousePosition);
       
        Collider2D[] col = Physics2D.OverlapPointAll(v);

        List<string> words = new List<string>();

        if(col.Length > 0){
            foreach(Collider2D c in col) {
                Debug.Log("Collided with: " + c.collider2D.gameObject.name);
                targetPos = c.collider2D.gameObject.transform.position;
                //Load values from Piecscore.cs
                PieceScore select = c.GetComponent<PieceScore>();
                //Change isSelected to True
                select.isSelected = true;
                //Load changed value into new Variable
                getSelect = select.isSelected;
                //Load letter
                letters = select.letter;
                //Load Color
                color = select.color;
                //Load Shape
                shape = select.shape;
                //Load Score
                score = select.score;
            }
        }
        if (getSelect == true) {

            for (int i=0; i<col.Length; i++) {
                   
                    words.Add(letters);
               
            }
        }
    }

Yes I am using “usingSystem.Collections.Generic;” and I’m getting no error codes. I’m lost and no amount of canned documentation will help. Would appreciate the communities support.

You declared your list inside ScreenMouseRay(), so it only lives while that function is active and is destroyed when it’s finished.

Hmm. That’s strange. I thought i was passing it into an external Variable.

public class GamePlay : MonoBehaviour {

    #region Variables
    public Vector3 targetPos;  // used in Raycasting
    public string ControlType = "PC";
    public string[] shapes;
    public string[] words;
    public string[] colors;
    public string letters;
    public string color;
    public string shape;
    public int score;
    public bool getSelect;
    public bool select = false;
    public bool click;



    #endregion

    #region Raycasting - Detects collisions with 2D colliders, SELECT piece, and pass info to arrays
    void ScreenMouseRay() { 

        Vector3 mousePosition = Input.mousePosition;
        mousePosition.z = 10f;
     
        Vector2 v = Camera.main.ScreenToWorldPoint(mousePosition);
     
        Collider2D[] col = Physics2D.OverlapPointAll(v);

        List<string> words = new List<string>();

        if(col.Length > 0){
            foreach(Collider2D c in col) {
                Debug.Log("Collided with: " + c.collider2D.gameObject.name);
                targetPos = c.collider2D.gameObject.transform.position;
                //Load values from Piecscore.cs
                PieceScore select = c.GetComponent<PieceScore>();
                //Change isSelected to True
                select.isSelected = true;
                //Load changed value into new Variable
                getSelect = select.isSelected;
                //Load letter
                letters = select.letter;
                //Load Color
                color = select.color;
                //Load Shape
                shape = select.shape;
                //Load Score
                score = select.score;
            }
        }
        if (getSelect == true) {

            for (int i=0; i<col.Length; i++) {
                 
                    words.Add(letters);
             
            }
        }
    }

    #endregion

Now when I take List words = newList(); out of the function, it says I have already defined words. Commenting out the public string[ ] words; fixes that error, but then I can’t see what is going in the list or if it is working. Perhaps I should be using a coroutine? ← Ok tried that and apparently no.

You’ve still got two different variables named “words”. First decide if you want to use an array or a list. It looks like most of your code is written assuming it’s a List so to stick with that, change line 7 to “public List words;” and then in line 31 it should just be “words = new List();”. Don’t put the type List in front, doing that means you are declaring a new variable instead of using an existing one.

That definitely helped. I can now populate the list. However I’m still having the same problem that I was having with the array version. The list will overwrite the prior selection rather than populate it with each selection.

Well still stuck. At a few things actually. Here is my full code:

using UnityEngine;
using System.Collections;
using System.Threading;
using System.Collections.Generic;

public class GamePlay : MonoBehaviour {

    #region Variables
    public Vector3 targetPos;  // used in Raycasting
    public string ControlType = "PC";  //TBD   
    public string[] shapes;
    public List<string> words;
    public string wordfin;
    public string[] colors;
    public string letters;
    public string color;
    public string shape;
    public int score;
    public bool getSelect;
    public bool selected = false;
    public bool click = false;



    #endregion

    #region Raycasting - Detects collisions with 2D colliders, SELECT piece, and pass info to arrays
    void ScreenMouseRay() {   

        Vector3 mousePosition = Input.mousePosition;
        mousePosition.z = 10f;
       
        Vector2 v = Camera.main.ScreenToWorldPoint(mousePosition);
       
        Collider2D[] col = Physics2D.OverlapPointAll(v);

        words = new List<string>();

        if(col.Length > 0){
            foreach(Collider2D c in col) {
                Debug.Log("Collided with: " + c.collider2D.gameObject.name);
                targetPos = c.collider2D.gameObject.transform.position;
                //Load values from Piecscore.cs
                PieceScore select = c.GetComponent<PieceScore>();
                //Change isSelected to True
                select.isSelected = true;
                //Load changed value into new Variable
                getSelect = select.isSelected;
                //Load letter
                letters = select.letter;
                //Load Color
                color = select.color;
                //Load Shape
                shape = select.shape;
                //Load Score
                score = select.score;
            }
        }
        if (getSelect == true) {
            for (int i=0; i<col.Length; i++) {                   
                words.Add(letters);
                Debug.Log("Selected: " + words);
               
            }
        }
    }

    #endregion

   

    #region PC Mouse Controls
    void RayCastingMouse() {

        if (Input.GetMouseButton(0)) {
            click = !click;
        }
        if (click == true) {
            Debug.Log("Pressed left click.");
            ScreenMouseRay();
        }
        else {
       
        }
       
    }
    #endregion
   
    #region Mobile Controls iOS
    void RayCastingTouchiOS() {

    }
    #endregion

    #region Mobile Controls Andriod
    void RayCastingTouchGoog() {
   
    }
    #endregion


 
    void Score() {
        string wordfin = string.Join(",", words.ToArray());
    }

    void RemovePieces() {
        //Remove Pieces when a value is returned positive
    }

    void SpawnNewPieces() {
        //Check each row to see how many are left from each spawner By accessing Spawntracker.cs (See SpawnPieces.cs IEnumerator StartGame() for example)
        //Check against maxPieces from SpawnPieces.cs
        //Spawn From that particular Spawner until total = maxPieces
        //Be sure to use the fSpawnDelay from SpawnPieces.cs to stay consistent
    }

    // Use this for initialization
    void Start () {
   
    }
    // Update is called once per frame
    void Update () {
   
        //to do to value if it is false
        if(selected == false) {
            RayCastingMouse();
            }   
        else {
       
        }
    }
}

So I’m trying to get the list words to populate with values which are grabbed off a component I already set up. The idea is that I fire a ray and hit the game object’s collider and select the values of the component and pass them into the list, then I take the list and turn it into a string to test.

Well I’m still not able to get the list to populate. It just grabs value #1 and writes the value of the currently selected object, then it overwrites that with the next selected value rather than making the next value list item #2. I can’t seem to understand what I am doing wrong here. How can I change this to make it work like I need it to?

Another annoying thing is with my mouse controls.

if (Input.GetMouseButton(0)) {
            click = !click;
        }
        if (click == true) {
            Debug.Log("Pressed left click.");
            ScreenMouseRay();

This works by detecting the mouse click and then making that turn a bool value on and off (T & F). This drives function. The idea is that you click the mouse the first time which activates the function and it deactivates when you click it again. The problem is the actual detection is very buggy. Sometimes the click is detected, sometimes it isn’t. Is there a more reliable way to detect this or is it always buggy?

Line 50, I think you want this:
letters += select.letter;

but you would want to clear it before the for loop starts or after it’s added to the words list.
That’s just a guess because I’m not really sure what you are doing, but you are stepping through a loop and you named it letters, as if you want more than one.
One common mistake new authors make is putting down too much code. It’s best to write small blocks and make sure it works the way you expect before continuing. This should have been better debugged at it’s current stage than it is.