-1

I have a weird problem.Everything just worked fine and sudenly i cant reach my list from another script.I simply do not understand why. It looks like that my instance is deleted by this second script when pressing play in unity. List is shown in Unity inspector and it is populated how i expected.But when calling List in second script in Debug it shows that lenght of list is 0;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class listePoretka : MonoBehaviour
{
    public static listePoretka instance1;
    int broj;
    public List<int> lista = new List<int>();
     int[] lista1 = { 7, 17, 28, 36, 45, 49, 56, 62, 67, 76, 81, 87, 94, 98, 107, 115, 126, 136, };
  int[] lista2 = { 4, 20, 29, 42, 51, 55, 59, 62, 71, 74, 82, 85, 89, 93, 102, 115, 124, 140 };
  int[] lista3 = {7,17,28,32,39,45,55,60,66,77,83,88,98,104,111,115,126,136 };
    int[] lista4 = { 7,18,33,39,41,52,61,68,71,72,75,82,91,102,104,110,125,136};
    int[] lista5 = { 8, 18, 29, 40, 47, 50, 58, 63, 67, 76, 80, 85, 93, 96, 103, 114, 125, 135 };
   
   // public int[,] dimenzijeUkrstenice;
    // Start is called before the first frame update
    public int[][] listaLista;

    void Awake()
    {
        if (instance1 == null)
        {
            instance1 = this;
        }
        else
        {
            Destroy(instance1);
        }
     
    }


    void Start()
    {

        broj = PlayerPrefs.GetInt("ukrstenica");
        listaLista = new int[][] { lista1, lista2,lista3 ,lista4,lista5};
        Debug.Log(listaLista[broj].Length);
   
       
      //  dimenzijeUkrstenice = new int[,] { { duzineRijeci.instance.duzinaH,duzineRijeci.instance.duzinaV }  };
    
     foreach (int i in listaLista[broj])
        {
            lista.Add(i);
            Debug.Log("is adding");

        }
    }

   

    
}

This is the code of script I am trying to reach in another script.And below is code of script where I am reaching first script:

public class ukrstenicaGrid : MonoBehaviour
{
    public static ukrstenicaGrid instance;

    public Text horizontalno;
    public Text vertikalno;

    public GameObject panelWin;

    public static string maliBroj;
    int kojiIndex = 1;
    int brojUmalomTekstu = 1;

   int brojGrida=0;

    int brojUmalomDrugi = 1;

    private int rows=12;
    private int columns = 12;
    public Image canvas;
    public Canvas kanvas;
    public float w;
    public float h;
    public float sirina;
    public float visina;

    Vector2 skala;
  
    public float squareScale = 1.0f;
    public float squareGap = 0.1f;
    public float squareOfser = 0.0f;

  
   


    float razmak = 0.5f;
   

    public Vector2 startPostition = new Vector2(0.0f, 0.0f);
    float pocetnaX;

    public GameObject gridUkrstenica;
    private List<GameObject> gridovi = new List<GameObject>();

    void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else { Destroy(instance); }
    }
    void Start()
    {
      rows = 12;
        columns = 12;
        skala = kanvas.transform.localScale;
        Debug.Log(skala);
         h = canvas.GetComponent<RectTransform>().rect.height*skala.y;
          w = kanvas.GetComponent<RectTransform>().rect.width* skala.x;
        sirina = w / (float)columns-razmak/columns;
        visina = h / rows-razmak/rows;
    
        
        spawnGrids();
        setSquarePositions();
        getTagH();
        // getTagV();
        probajTag();
        obrisiSakeceva();
      //  dodajSlova();
    }


   private void spawnGrids()
    {
       
    
        float visinaCela;
        float visinaSvihCelija;
        h = canvas.GetComponent<RectTransform>().rect.height * skala.y;
        

        for (int row = 0; row < rows; row++)
        {
           

            for (int column = 0; column < columns; column++)
            {
               
                GameObject gridavi = (GameObject)Instantiate(gridUkrstenica) as GameObject;
                //Instantacija gameobjekta u listu gameobjekata
            //    gridovi[gridovi.Count - 1].GetComponent<testing>().setSquareIndex(brojGrida);
                //Postavljanje objekta kao childa od objekta koji drzi skriptu
                gridovi.Add(gridavi);  //Postavljanje objekta kao childa od objekta koji drzi skriptu
                gridovi[gridovi.Count - 1].transform.parent = this.transform;
                gridovi[gridovi.Count - 1].GetComponent<klikUkrstenica>().setSquareIndex(brojGrida);
                maliBroj = kojiIndex.ToString();
                
                gridovi[gridovi.Count - 1] .GetComponent< RectTransform>().sizeDelta = new Vector2(w/columns, h/rows);
               
                //Visina jedne celije
                visinaCela = gridovi[0].GetComponent<RectTransform>().rect.height;
                visinaSvihCelija = visinaCela * rows;
             

                startPostition = new Vector2(((0 - w / 2) - razmak+(gridovi[0].GetComponent
                    <RectTransform>().rect.width/2))/skala.x,(0+h/2-visinaCela/2)/skala.y);

                gridovi[gridovi.Count - 1].GetComponent<klikUkrstenica>().drugiText.GetComponent<Text>().text=maliBroj ;

                pocetnaX = startPostition.x;

                brojGrida++;
                kojiIndex++;
            }
        }
        Debug.Log("velicina liste" + listePoretka.instance1.lista);

        foreach (int i in listePoretka.instance1.lista)
        {
            gridovi[i].GetComponent<Image>().color = Color.black;
            gridovi[i].GetComponentInChildren<Text>().text = "1";
        }

       
      

    }

I have tried also using public static List,but prblem is same.

derHugo
  • 83,094
  • 9
  • 75
  • 115
bata kos
  • 91
  • 5
  • 2
    You should initialize your `listePoretka` in `Awake`, rather than `Start`. This way, when `ukrstenicaGrid.Start` is called, everything is already initialized. Does this answer your question? [Awake() and Start()](https://stackoverflow.com/questions/34652036/awake-and-start) – Ruzihm Feb 01 '22 at 14:43

1 Answers1

0
  • I'm pretty sure this is a execution order issue.

    There is no guarantee that listePoretka.Start is executed before ukrstenicaGrid.Start.

    My personal general thumb rule on this:

    • Use Awake to initialize everything where you do not rely on others (e.g. for GetComponent calls, initialize fields etc)
    • Use Start where you do rely on others (like accessing fields of other components)

    This solves most of order based issues.

    Where this isn't enough you can still play with the Script Execution Order or use a more complex event system.

    So you should probably move the content of listePoretka.Start into listePoretka.Awake which would already solve your issue most probably.

  • Another issue: Your singleton initialization makes no sense!

    If instance1 != null then you want to destroy yourself not the already existing instance!

So in listePoretka rather do e.g.

void Awake()
{
    if (instance1 && intance != this)
    {
        Destroy(gameObject);
        return;
    }

    instance1 = this;

    broj = PlayerPrefs.GetInt("ukrstenica");
    listaLista = { lista1, lista2,lista3 ,lista4,lista5};
    Debug.Log(listaLista[broj].Length);

    foreach (int i in listaLista[broj])
    {
        lista.Add(i);
        Debug.Log("is adding");
    }
}

In general using Singletons is very questionable and most of the time not really needed (it's just lazy).

Rather have proper fields

[SerializeField] private listePoretka _listePoretka;

and reference the according object by drag&drop into this field via the Inspector in Unity.

Or if you need it on runtime (e.g. later instantiated objects) you could use FindObjectOfType


However, in your case the listePoretka actually I don't see any reason why this should be a MonoBehaviour at all.

It could as well just be

public static class listePoretka
{
    private static int broj;

    // Simply return the according array - no need to copy it over into a list
    public static IReadOnlyList<int> lista => _listaLista[broj];

    private static readonly int[] lista1 = { 7, 17, 28, 36, 45, 49, 56, 62, 67, 76, 81, 87, 94, 98, 107, 115, 126, 136, };
    private static readonly int[] lista2 = { 4, 20, 29, 42, 51, 55, 59, 62, 71, 74, 82, 85, 89, 93, 102, 115, 124, 140 };
    private static readonly int[] lista3 = { 7, 17, 28, 32, 39, 45, 55, 60, 66, 77, 83, 88, 98, 104, 111, 115, 126, 136 };
    private static readonly int[] lista4 = { 7, 18, 33, 39, 41, 52, 61, 68, 71, 72, 75, 82, 91, 102, 104, 110, 125, 136 };
    private static readonly int[] lista5 = { 8, 18, 29, 40, 47, 50, 58, 63, 67, 76, 80, 85, 93, 96, 103, 114, 125, 135 };

    public static int[][] listaLista => _listaLista;

    // since all the arrays now are static anyway you can directly use them in static field initialization context
    private static int[][] _listaLista = { lista1, lista2, lista3, lista4, lista5 };

    // This method is called AFTER Awake but BEFORE Start!
    // See https://docs.unity3d.com/ScriptReference/RuntimeInitializeOnLoadMethodAttribute.html
    [RuntimeInitializeOnLoadMethod]
    private static void Initialize()
    {
        broj = PlayerPrefs.GetInt("ukrstenica");
        Debug.Log(listaLista[broj].Length);
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115