I don’t know if there’s something I’m completely missing here or if I’m going nuts, but I’m right now having an issue with array fields not being initialized to null, but to arrays with 0 elements, and this is damned scary. They are private fields, not used anywhere (in fact I just created a few of them to test this), on a plain class (not MonoBehaviour
, but Serializable
). What on Earth is going on?
This is the class file untouched, for example the fields that start as non-null are ae
, go
and ints
, which I just created to test:
using System;
using System.Collections.ObjectModel;
using UnityEngine;
namespace Trisibo
{
[Serializable]
public class QuizDataEntry
{
#region Parameters
/// <summary>The question.</summary>
public QuizQuestion Question => question;
[SerializeField] QuizQuestion question = null;
/// <summary>All the answers.</summary>
public ReadOnlyCollection<AnswerEntry> Answers => _readOnlyAnswers ?? (_readOnlyAnswers = new ReadOnlyCollection<AnswerEntry>(answers));
ReadOnlyCollection<AnswerEntry> _readOnlyAnswers;
[Space]
[CollectionDrawer(elementsSeparation: 10)]
[SerializeField] AnswerEntry[] answers = null;
#endregion
#region Data types
/// <summary>
/// An answer entry.
/// </summary>
[Serializable]
public class AnswerEntry
{
/// <summary>The type of answer.</summary>
public AnswerType AnswerType => answerType;
[SerializeField] AnswerType answerType;
/// <summary>The answer.</summary>
public QuizAnswer Answer => answer;
[SerializeField] QuizAnswer answer;
}
/// <summary>
/// The type of answer.
/// </summary>
public enum AnswerType
{
/// <summary>The answer is wrong.</summary>
Wrong = 0,
/// <summary>The answer is correct.</summary>
Correct = 10,
}
#endregion
/// <summary>
/// Gets the shuffled answers.
/// Initialize or update them using <see cref="UpdateShuffledAnswers"/>, even the first time the property is accessed.
/// The order of the answers will be the same for all accesses until the next call to <see cref="UpdateShuffledAnswers"/>.
/// </summary>
public ReadOnlyCollection<AnswerEntry> ShuffledAnswers
{
get
{
if (_shuffledAnswers == null)
{
_shuffledAnswers = new AnswerEntry[answers.Length];
Array.Copy(answers, _shuffledAnswers, answers.Length);
_readOnlyShuffledAnswers = new ReadOnlyCollection<AnswerEntry>(_shuffledAnswers);
}
return _readOnlyShuffledAnswers;
}
}
ReadOnlyCollection<AnswerEntry> _readOnlyShuffledAnswers;
AnswerEntry[] _shuffledAnswers;
private AnswerEntry[] ae;
private GameObject[] go;
private int[] ints;
/// <summary>
/// Shuffles <see cref="ShuffledAnswers"/>.
/// </summary>
/// <param name="maxShownAnswers">The max number of answers that will be shown. Necessary to ensure a correct answer will be shown.</param>
public void UpdateShuffledAnswers(int maxShownAnswers)
{
var _ = ShuffledAnswers; //-> Ensure that it's initialized.
_shuffledAnswers.Shuffle();
// Ensure there's a correct answer in the ones that will be shown:
if (maxShownAnswers < _shuffledAnswers.Length)
{
int correctAnswerIndex;
for (correctAnswerIndex = 0; correctAnswerIndex < _shuffledAnswers.Length; correctAnswerIndex++)
{
if (_shuffledAnswers[correctAnswerIndex].AnswerType == AnswerType.Correct)
break;
}
if (correctAnswerIndex < _shuffledAnswers.Length && correctAnswerIndex >= maxShownAnswers)
{
int otherIndex = UnityEngine.Random.Range(0, maxShownAnswers);
var tmp = _shuffledAnswers[otherIndex];
_shuffledAnswers[otherIndex] = _shuffledAnswers[correctAnswerIndex];
_shuffledAnswers[correctAnswerIndex] = tmp;
}
}
}
}
}