Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Array is empty even though it is initialized in Start()

Discussion in 'Scripting' started by jettzeong, May 9, 2023.

  1. jettzeong

    jettzeong

    Joined:
    Nov 5, 2018
    Posts:
    65
    Currently I am making a chess game, and I have an issue where I want to call Highlight() in BoardController, but it is empty when I call it, even though I have instantiated it in the Start() method.

    This is my BoardController class:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class BoardController : MonoBehaviour
    6. {
    7.     [SerializeField] private Piece[] positions;
    8.     [SerializeField] private GameObject[] blueHighlight;
    9.     [SerializeField] private GameObject highlightSquare;
    10.     void Start()
    11.     {
    12.         InstantiatePieces();
    13.     }
    14.  
    15.     private void InstantiatePieces()
    16.     {
    17.         blueHighlight = new GameObject[64];
    18.  
    19.         for (int i = 0; i < 64; i++)
    20.         {
    21.             int x = i % 8;
    22.             int y = i / 8;
    23.  
    24.             blueHighlight[i] = Instantiate(highlightSquare, new Vector3(x, y, 0), Quaternion.identity);
    25.  
    26.             if (positions[i] != null)
    27.             {
    28.                 Instantiate(positions[i], new Vector3(x, y, 0), Quaternion.identity);
    29.             }
    30.         }
    31.     }
    32.  
    33.     private void Update()
    34.     {
    35.        
    36.     }
    37.  
    38.     public bool IsLegalMove(int x, int y)
    39.     {
    40.         int pos = y * 8 + x;
    41.         if (positions[pos] != null || !IsInBounds(x, y))
    42.         {
    43.             // change based on black or white;
    44.             return false;
    45.         }
    46.  
    47.         return true;
    48.     }
    49.  
    50.     public bool IsInBounds(int x, int y)
    51.     {
    52.         if (x < 0 || x > 7 || y < 0 || y > 7)
    53.         {
    54.             return false;
    55.         }
    56.  
    57.         return true;
    58.     }
    59.  
    60.     public void Highlight(int x, int y)
    61.     {
    62.         Debug.Log("Highlight");
    63.         int pos = ConvertToPos(x, y);
    64.         blueHighlight[pos].SetActive(true);
    65.         Debug.Log("Completed");
    66.     }
    67.  
    68.     // Converts (x, y) coords to 0 - 63
    69.     public int ConvertToPos(int x, int y)
    70.     {
    71.         return y * 8 + x;
    72.     }
    73.  
    74.     public int[] ConvertToXY(int pos)
    75.     {
    76.         return new int[] { pos % 8, pos / 8 };
    77.     }
    78. }
    79.  
    And this is the Rook class:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Rook : Piece
    6. {
    7.     public int[,] delta = new int[1, 2] {{0, 1}};
    8.  
    9.     private void Start()
    10.     {
    11.         base.Start();
    12.     }
    13.  
    14.     public override void GetAvailableMoves()
    15.     {
    16.         for (int i = 0; i < delta.Length - 1; i++)
    17.         {
    18.             int x = delta[i, 0];
    19.             int y = delta[i, 1];
    20.             if (boardController.IsLegalMove(x, y))
    21.             {
    22.                 Debug.Log("Legal");
    23.                 boardController.Highlight(x, y);
    24.             }
    25.         }
    26.  
    27.     }
    28. }
    29.  
    What I wanted to do is that when I click on the Rook piece, it will highlight the square it is sitting on, but I get an IndexOutOfBounds error since the blueHighlight array has length of 0 for some reason, even though I initialized it at the start
     
  2. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    What is "boardController" inside your Rook class? It's probably a field that comes from the "Piece" class I guess? What and where did you assign something to that variable? My guess is that you may have assigned a prefab to that variable but you never assigned the actual instance in the scene to that variable.

    You can verify which object you're referencing by using a Debug.Log statement and pass the object you want to know as a context argument. Like this:

    Code (CSharp):
    1. Debug.Log("Rook's boardController", boardController);
    When you click on that log message, the Unity editor will highlight / ping the passed context object in the hierarchy / project. So you know if you're dealing with the correct object. The same thing can be checked at runtime by simply clicking on the "boardController" object field of your rook instance. This should also highlight the referenced object. As I said, my guess is that the object is not the object you have in mind.

    We don't know how your pieces get instantiated. Though you probably want to assign the board controller when you create the pieces, or use a singleton instead. A singleton is a cheap workaround. Actually assigning the reference when you instantiate the pieces would allow you to create several boards in your game and each has its own board controller. You probably don't need this, but it shows the difference in flexibility.