NullReferenceException при доступе к элементу массива из другого скрипта - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть два объекта: Tile и TileGrid , которые имеют свои собственные сценарии.TileGrid может генерировать 2d массив плиток.Затем я пытаюсь прикрепить каждую плитку вокруг плитки в сценарии для каждой плитки, поэтому все мои плитки будут иметь ссылку на своих «соседей».Я использую словарь.Для этого я написал функцию, которая обращается к 2d массиву плиток TileGrid.К сожалению, NullReferenceException выбрасывается.

TileGridScript.cs

public class TileGridScript : MonoBehaviour
{
    public GameObject[][] tileGrid;
    // Other properties ...
    public void MakeGrid(int width = 64, int height = 64)
    {
        tileGrid = new GameObject[width][];
        for (int x = 0; x < width; x++)
        {
            tileGrid[x] = new GameObject[height];
            for (int y = 0; y < height; y++)
            {
                // !!! Instantiating tiles !!!
                tileGrid[x][y] = Instantiate(grassPrefab, new Vector2(x - width / 2, y - height / 2), Quaternion.identity);
            }
        }
        // !!! Call the function to connect Tiles !!!
        for (int x = 0; x < width; x++)
            for (int y = 0; y < height; y++)
                tileGrid[x][y].GetComponent<TileScript>().AttchTile(this);
    }
}

TileScript.cs

public class TileScript : MonoBehaviour
{
    public Dictionary<string, GameObject> connectedTiles;
    // Other properties ...
    private void Start()
    {
        connectedTiles = new Dictionary<string, GameObject>(8);
    }
    public void AttchTile (TileGridScript tileGridScript)
    {
        for (int biasx = -1; biasx < 2; biasx++)
        {
            for (int biasy = -1; biasy < 2; biasy++)
            {

                switch (biasx)
                {
                    case -1: // L
                        switch (biasy)
                        {
                            case -1: // D
                                try
                                {
                                    // !!! Catches the error here !!!
                                    connectedTiles["DL"] = tileGridScript.tileGrid[(int)position.x + biasx][(int)position.y + biasy]; 
                                }
                                catch (System.IndexOutOfRangeException) { }
                                break;
                        }
                    // etc for every Tile. P.S. DL means Down and Left.
                    // in this way I add all 8 Tiles around that
                }
            }
        }
    }
}

GameManager.cs

public class GameManager : MonoBehaviour
{
    public GameObject tileGridPrefab;
    // Other properties...
    void Start()
    {
        // !!! Here I generate the Tile Grid !!!
        tileGridPrefab.GetComponent<TileGridScript>().MakeGrid(24, 16);
    }
}

Я пытался написать эту функцию в скрипте TileGrid и вызвать ее из этого.Если я не инициализирую словарь в Start (), это нормально.Затем, когда я получаю доступ к нему из другого скрипта, он падает с той же ошибкой.Я попытался изменить порядок этих скриптов в редакторе.

В чем причина проблемы и как я могу ее исправить?

1 Ответ

0 голосов
/ 31 декабря 2018

Проблема в том, что Start() звонит после AttachTile().

Я должен использовать Awake() вместо этого.Я получаю TileGrid объект в Awake(), а затем могу использовать его в AttachTile() функции.

...