Instead of multiple lists that happened to be in sync with one another. I’d use a single list (or any collection) of some data contract.
[System.Serializable]//the serializable attribute will be brought up later in this post
public struct MusicTrackInfo
{
public string TrackName;
public string Author;
public string ReleaseDate;
}
and the list:
List<MusicTrackInfo> MusicTracks = new List<MusicTrackInfo>() {
new MusicTrackInfo() { TrackName="Poker Face", Author="Lady Gaga", ReleaseDate="" },
new MusicTrackInfo() { TrackName="Stinkfist", Author="Tool", ReleaseDate="" }
};
This was you could also store all the track info in a json file which is easily modifiable (this is where the serializable attribute comes into play):
{
Tracks:[
{ TrackName:"Poker Face", Author:"Lady Gaga", ReleaseDate:"" },
{ TrackName:"Stinkfist", Author:"Tool", ReleaseDate:"" }
]
}
And this could be parsed into a list:
[System.Serializable]
public class TrackContainer
{
public List<MusicTrackInfo> Tracks;
}
//else where
var trackcontainer = JsonUtility.FromJson<TrackContainer>(someJsonYouLoaded);
foreach(var track in trackcontainer.Tracks)
{
Debug.Log(track.TrackName);
}
(Note - I only created this TrackContainer because Unity in some weird decision decided to only support json that starts as an object as its root, and not an array as its root. Why? Ask Unity’s engineers. It’s likely because they just tapped into their existing deserialization engine which up to this point would never have a situation where you’d deserialize to an array/list but rather some Asset/GameObject/ScriptableObject.)
Now lets say you had a list of buttons that were in sync with this index to index. You could do:
var buttons = new List<Button>() { ...the buttons };
for(int i = 0; i < buttons.Count; i++)
{
var info = trackcontainer.Tracks[i];
buttons[i].onClick.AddListener(() => DisplayMusicInfo(info));
}
Where your method that used to take an index to display the track info now takes the MusicTrackInfo:
public void DisplayMusicInfo(MusicTrackInfo info)
{
trackNameDisplay.text = info.TrackName;
trackAuthorDisplay.text = info.Author;
trackDateDisplay.text = info.ReleaseDate;
}
Although this sounds really weird to me… I would probably assume it could be the other way around. Where the button list is created from the list of songs. Like say you had a scroll view with a new line entry for every track.
foreach(var track in trackcontainer.Tracks)
{
var btn = CreateButton();
btn.onClick.AddListener(() => PlayTrack(track));
AddButtonToDisplayScrollView(track, btn);
}
And now down the line lets say you want to add more info to the json for the tracks… like say the AlbumName. Well then you just modify the data contract:
[System.Serializable]
public struct MusicTrackInfo
{
public string TrackName;
public string Author;
public string ReleaseDate;
public string AlbumName;
}
You add that to the json:
{
Tracks:[
{ TrackName:"Poker Face", Author:"Lady Gaga", ReleaseDate:"", AlbumName:"The Fame" },
{ TrackName:"Stinkfist", Author:"Tool", ReleaseDate:"", AlbumName:"Aenima"}
]
}
And all the existing code continue working.
NOTE: all code in this post was written in-line, likely contains spelling errors, and is really intended for demonstration purposes.