【问题标题】:Geting a List value from another script [duplicate]从另一个脚本获取列表值[重复]
【发布时间】:2022-02-01 23:01:38
【问题描述】:

我有一个奇怪的问题。一切正常,突然间我无法从另一个脚本访问我的列表。我只是不明白为什么。 看起来我的实例在统一按下播放时被第二个脚本删除了。 列表显示在 Unity 检查器中,它按照我的预期填充。但是在调试的第二个脚本中调用列表时,它显示列表的长度为 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");

        }
    }

   

    
}

这是我试图在另一个脚本中到达的脚本代码。下面是我到达第一个脚本的脚本代码:

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";
        }

       
      

    }

我也尝试过使用公共静态列表,但问题是一样的。

【问题讨论】:

  • 你应该在Awake中初始化你的listePoretka,而不是Start。这样,当调用ukrstenicaGrid.Start 时,一切都已经初始化。这回答了你的问题了吗? Awake() and Start()

标签: c# list unity3d


【解决方案1】:
  • 我很确定这是执行顺序问题。

    不保证listePoretka.Start之前ukrstenicaGrid.Start被执行。

    我个人对此的一般经验法则:

    • 使用Awake 初始化您不依赖他人的所有内容(例如,GetComponent 调用、初始化字段等)
    • 在您确实依赖他人的地方使用Start(例如访问其他组件的字段)

    这解决了大多数基于订单的问题。

    如果这还不够,您仍然可以使用Script Execution Order 或使用更复杂的事件系统。

    因此,您可能应该将listePoretka.Start 的内容移动到listePoretka.Awake,这很可能已经解决了您的问题。

  • 另一个问题:你的单例初始化没有意义!

    如果是instance1 != null,那么你想销毁你自己而不是已经存在的实例!

所以在listePoretka 宁可做例如

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");
    }
}

一般来说,使用 Singletons 是非常有问题的,而且大多数时候并不真正需要(它只是懒惰)。

相当有合适的字段

[SerializeField] private listePoretka _listePoretka;

并通过 Unity 中的 Inspector 拖放到此字段中来引用相应的对象。

或者,如果您在运行时需要它(例如稍后实例化的对象),您可以使用 FindObjectOfType


但是,在您的情况下,listePoretka 实际上我看不出有任何理由为什么这应该是 MonoBehaviour

也可以

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);
    }
}

【讨论】:

    猜你喜欢
    • 2021-05-06
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多