Значения нулевого элемента массива объектов отображаются некорректно
Есть область/поле, в которую генерируются ячейки. Ячейки при создании получают данные из ScriptableObject в рандомном порядке, но почему-то получается так, что 0ой элемент данные не получает, или получает, но последнее значение предыдущей генерации. Например: (1ый запуск: null, 1, 2 => 2ой: 2, 2, 1 => 3ий: 1, 2, 1). Я сделал костыль, создавая на 1 элемент больше, и удаляя 0ой элемент, что в принципе решило проблему, но получаю ошибку:
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
Получается, что я вышел за диапазон, но как это поправить без костылей, не понимаю. Может кто-нибудь помочь разобраться?
public class Field : MonoBehaviour
{
[Tooltip("Список настроек для иконок")]
[SerializeField] private List<CardData> cardDataList;
[Tooltip("Кол-во объектов в пуле")]
[SerializeField] private int FieldSize;
[Tooltip("Базовый префаб иконок")]
[SerializeField] private GameObject cellPref;
[SerializeField] private float CellSize;
[SerializeField] private float Spacing;
[SerializeField] private RectTransform rt;
private Cell cellCell;
private GameObject[] field;
private int rand;
private List<int> randomList = new List<int>();
void Start()
{
randomList = new List<int>(new int[cardDataList.Count]);
GenerateField();
}
private void CreateField()
{
randomWithoutDuplicate();
field = new GameObject[FieldSize]; //инициализируем массив
float fieldWidth = FieldSize * (CellSize + Spacing) + Spacing; // считаем ширину поля
rt.sizeDelta = new Vector2(fieldWidth, CellSize + Spacing); // устанавливаем размер на canvas
float startX = -(fieldWidth / 2) + (CellSize / 2) + Spacing; // нач.позиции для первой клетки
float startY = (fieldWidth / 2) - (CellSize / 2) - Spacing;
var sprite = cellPref.GetComponent<Cell>();
//заполняем поле и создаём объекты по префабу
for (int x = 0; x < FieldSize+1; x++)
{
var cell = Instantiate(cellPref, transform, false); //startY - (y * (CellSize + Spacing))
sprite.Init(cardDataList[randomList[x]-1]); // присваиваем элементу данные из базы cardDataList
Debug.Log(cardDataList[randomList[x]-1] + " <<=====");
var position = new Vector2(startX + (x * (CellSize + Spacing)), 0);
cell.transform.localPosition = position;
field[x] = cell; // созданный объект заносим в массив
if(field[0])
Destroy(field[0]); // костыль удаляющий неправильно заполняющийся элемент
}
}
private void randomWithoutDuplicate()
{
for (int i = 0; i < cardDataList.Count; i++)
{
rand = UnityEngine.Random.Range(1, cardDataList.Count + 1);
while (randomList.Contains(rand))
{
rand = UnityEngine.Random.Range(1, cardDataList.Count + 1);
}
randomList[i] = rand;
Debug.Log(randomList[i]);
}
}
private void GenerateField()
{
if (field == null)
}
}
Ответы (2 шт):
Используя в цикле Length или Count, вроде как всегда нужно прописывать -1, то есть:
for(int i =0; i <= (carDataList.Count - 1); i++)
Оказалось, что sprite.Init(cardDataList[randomList[x]-1]), который присваивал данные элементам надо было использовать ДО создания первого элемента (который и не получал данные). Сама рандомная генерация также претерпела изменения.
private void CreateField()
{
var asd = randomWithoutDuplicate(); // генерируем очередь без повторов
field = new GameObject[FieldSize]; //инициализируем массив
float fieldWidth = FieldSize * (CellSize + Spacing) + Spacing; // считаем ширину поля
rt.sizeDelta = new Vector2(fieldWidth, CellSize + Spacing); // устанавливаем размер на canvas
float startX = -(fieldWidth / 2) + (CellSize / 2) + Spacing; // нач.позиции для первой клетки
float startY = (fieldWidth / 2) - (CellSize / 2) - Spacing;
var sprite = cellPref.GetComponent<Cell>();
//заполняем поле и создаём объекты по префабу
for (int x = 0; x < field.Length; x++)
{
sprite.Init(cardDataList[asd[x]]); //передаём данные до создания 1ого элемента, иначе он не будет получать данные
var cell = Instantiate(cellPref, transform, false);
var position = new Vector2(startX + (x * (CellSize + Spacing)), 0);
cell.transform.localPosition = position;
field[x] = cell; // созданный объект заносим в массив
}
}
private List<int> randomWithoutDuplicate()
{
var rnd = new System.Random();
var randomNumbers = Enumerable.Range(0, cardDataList.Count).OrderBy(x => rnd.Next()).Take(cardDataList.Count).ToList();
return randomNumbers;
}
