Skip to content

Commit 972173c

Browse files
committed
Added new song class to C# libraries.
1 parent adbe345 commit 972173c

File tree

5 files changed

+245
-218
lines changed

5 files changed

+245
-218
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace RhythmGameUtilities
6+
{
7+
8+
public class Song
9+
{
10+
11+
private readonly Dictionary<string, KeyValuePair<string, string[]>[]> _sections;
12+
13+
public Dictionary<string, string> metaData { get; }
14+
15+
public int resolution { get; }
16+
17+
public Tempo[] tempoChanges { get; private set; }
18+
19+
public TimeSignature[] timeSignatureChanges { get; }
20+
21+
public Dictionary<Difficulty, Note[]> difficulties { get; private set; }
22+
23+
public BeatBar[] beatBars { get; private set; }
24+
25+
public Song(string contents)
26+
{
27+
_sections = Parsers.ParseSectionsFromChart(contents);
28+
29+
metaData = Parsers.ParseMetaDataFromChartSection(_sections
30+
.First(section => section.Key == NamedSection.Song)
31+
.Value);
32+
33+
resolution = int.Parse(metaData["Resolution"]);
34+
35+
tempoChanges = Parsers.ParseTempoChangesFromChartSection(_sections
36+
.First(section => section.Key == NamedSection.SyncTrack)
37+
.Value);
38+
39+
timeSignatureChanges = Parsers.ParseTimeSignatureChangesFromChartSection(_sections[NamedSection.SyncTrack]);
40+
41+
difficulties = Enum.GetValues(typeof(Difficulty))
42+
.Cast<Difficulty>()
43+
.Where(difficulty => _sections.ToDictionary(item => item.Key, x => x.Value)
44+
.ContainsKey($"{difficulty}Single"))
45+
.ToDictionary(difficulty => difficulty,
46+
difficulty => Parsers.ParseNotesFromChartSection(_sections[$"{difficulty}Single"]));
47+
48+
beatBars = Utilities.CalculateBeatBars(tempoChanges, includeHalfNotes : true);
49+
}
50+
51+
public void RecalculateBeatBarsWithSongLength(float songLength)
52+
{
53+
var lastTick = Utilities.ConvertSecondsToTicks(songLength, resolution, tempoChanges, timeSignatureChanges);
54+
55+
tempoChanges = Parsers.ParseTempoChangesFromChartSection(_sections
56+
.First(section => section.Key == NamedSection.SyncTrack)
57+
.Value);
58+
59+
tempoChanges = tempoChanges.Concat(new Tempo[]
60+
{
61+
new()
62+
{
63+
Position = Utilities.RoundUpToTheNearestMultiplier(lastTick, resolution),
64+
BPM = tempoChanges.Last().BPM
65+
}
66+
})
67+
.ToArray();
68+
69+
beatBars = Utilities.CalculateBeatBars(tempoChanges, includeHalfNotes : true);
70+
}
71+
72+
}
73+
74+
}

UnityPackage/Samples~/SampleSong (URP)/Scripts/RenderSong.cs

Lines changed: 47 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using System;
21
using System.Collections.Generic;
32
using System.IO;
4-
using System.Linq;
53
using System.Threading.Tasks;
64
using System.Web;
75
using RhythmGameUtilities;
@@ -51,67 +49,21 @@ public class RenderSong : MonoBehaviour
5149

5250
private readonly Vector3 _beatBarScaleQuarter = new(5, 0.03f, 0.01f);
5351

54-
public int resolution { get; set; } = 192;
55-
56-
public Tempo[] tempoChanges { get; set; }
57-
58-
public TimeSignature[] timeSignatureChanges { get; set; }
59-
60-
public Dictionary<Difficulty, Note[]> difficulties { get; set; }
61-
62-
public Dictionary<int, List<Note>> notesGroupedByHandPosition { get; set; }
63-
64-
public BeatBar[] beatBars { get; set; }
52+
private Song _song;
6553

6654
private async void Start()
6755
{
6856
var path = Path.Join(Application.dataPath, _songPath, "notes.chart");
6957

7058
var contents = await LoadTextFileFromPath($"file://{HttpUtility.UrlPathEncode(path)}");
7159

72-
var sections = Parsers.ParseSectionsFromChart(contents);
73-
74-
var metadata = Parsers.ParseMetaDataFromChartSection(sections
75-
.First(section => section.Key == NamedSection.Song)
76-
.Value);
60+
_song = new Song(contents);
7761

7862
_audioSource.clip =
7963
await LoadAudioFileFromPath(
80-
$"file://{HttpUtility.UrlPathEncode(Path.Join(Path.GetDirectoryName(path), metadata["MusicStream"]))}");
81-
82-
resolution = int.Parse(metadata["Resolution"]);
83-
84-
tempoChanges = Parsers.ParseTempoChangesFromChartSection(sections.First(section => section.Key == NamedSection.SyncTrack)
85-
.Value);
86-
87-
timeSignatureChanges = Parsers.ParseTimeSignatureChangesFromChartSection(sections[NamedSection.SyncTrack]);
88-
89-
var lastTick =
90-
Utilities.ConvertSecondsToTicks(_audioSource.clip.length, resolution, tempoChanges, timeSignatureChanges);
91-
92-
tempoChanges = tempoChanges.Concat(new Tempo[]
93-
{
94-
new()
95-
{
96-
Position = Utilities.RoundUpToTheNearestMultiplier(lastTick, resolution),
97-
BPM = tempoChanges.Last().BPM
98-
}
99-
})
100-
.ToArray();
101-
102-
difficulties = Enum.GetValues(typeof(Difficulty))
103-
.Cast<Difficulty>()
104-
.Where(difficulty => sections.ToDictionary(item => item.Key, x => x.Value)
105-
.ContainsKey($"{difficulty}Single"))
106-
.ToDictionary(difficulty => difficulty,
107-
difficulty => Parsers.ParseNotesFromChartSection(sections[$"{difficulty}Single"]));
64+
$"file://{HttpUtility.UrlPathEncode(Path.Join(Path.GetDirectoryName(path), _song.metaData["MusicStream"]))}");
10865

109-
notesGroupedByHandPosition = difficulties[Difficulty.Expert]
110-
.Where(note => note.HandPosition < 5)
111-
.GroupBy(note => note.HandPosition)
112-
.ToDictionary(group => group.Key, group => group.ToList());
113-
114-
beatBars = Utilities.CalculateBeatBars(tempoChanges, includeHalfNotes : true);
66+
_song.RecalculateBeatBarsWithSongLength(_audioSource.clip.length);
11567

11668
_audioSource.Play();
11769
}
@@ -161,18 +113,19 @@ private void Update()
161113
{
162114
RenderTrack();
163115

164-
if (notesGroupedByHandPosition == null)
116+
if (_song?.difficulties?[Difficulty.Easy] == null)
165117
{
166118
return;
167119
}
168120

169121
var tickOffset =
170-
Utilities.ConvertSecondsToTicks(_audioSource.time, resolution, tempoChanges, timeSignatureChanges);
122+
Utilities.ConvertSecondsToTicks(_audioSource.time, _song.resolution, _song.tempoChanges,
123+
_song.timeSignatureChanges);
171124

172-
RenderHitNotes(notesGroupedByHandPosition);
125+
RenderHitNotes();
173126

174-
RenderNotes(notesGroupedByHandPosition, resolution, tickOffset);
175-
RenderBeatBars(beatBars, resolution, tickOffset);
127+
RenderNotes(_song.difficulties[Difficulty.Easy], _song.resolution, tickOffset);
128+
RenderBeatBars(_song.beatBars, _song.resolution, tickOffset);
176129
}
177130

178131
private void RenderTrack()
@@ -183,51 +136,43 @@ private void RenderTrack()
183136
_trackMaterial, 0);
184137
}
185138

186-
private void RenderHitNotes(Dictionary<int, List<Note>> notesGroupedByHandPosition)
139+
private void RenderHitNotes()
187140
{
188-
for (var x = 0; x < notesGroupedByHandPosition.Count; x += 1)
141+
for (var x = 0; x < 5; x += 1)
189142
{
190143
Graphics.DrawMesh(_mesh,
191144
Matrix4x4.TRS(new Vector3(x + 0.5f, 0, 0), Quaternion.identity, _noteScaleFlat),
192145
_materials[x], 0);
193146
}
194147
}
195148

196-
private void RenderNotes(Dictionary<int, List<Note>> notesGroupedByHandPosition, int resolution, int tickOffset)
149+
private void RenderNotes(Note[] notes, int resolution, int tickOffset)
197150
{
198-
for (var x = 0; x < notesGroupedByHandPosition.Count; x += 1)
199-
{
200-
if (!notesGroupedByHandPosition.ContainsKey(x))
201-
{
202-
continue;
203-
}
204-
205-
var noteMatrix = new List<Matrix4x4>
206-
{
207-
Matrix4x4.TRS(new Vector3(x + 0.5f, 0, 0), Quaternion.identity, _noteScaleFlat)
208-
};
151+
var laneArray = new Dictionary<int, List<Matrix4x4>>();
209152

210-
for (var y = 0; y < notesGroupedByHandPosition[x].Count; y += 1)
211-
{
212-
var position = Utilities.ConvertTickToPosition(notesGroupedByHandPosition[x][y].Position - tickOffset,
213-
resolution) * _scale;
153+
for (var x = 0; x < 5; x += 1)
154+
{
155+
laneArray.Add(x, new List<Matrix4x4>());
156+
}
214157

215-
if (position > _distance)
216-
{
217-
break;
218-
}
158+
for (var i = 0; i < notes.Length; i += 1)
159+
{
160+
if (notes[i].HandPosition > 5) continue;
219161

220-
if (position < 0)
221-
{
222-
continue;
223-
}
162+
var position = Utilities.ConvertTickToPosition(notes[i].Position - tickOffset,
163+
resolution) * _scale;
224164

225-
noteMatrix.Add(Matrix4x4.TRS(
226-
new Vector3(notesGroupedByHandPosition[x][y].HandPosition + 0.5f, 0, position),
165+
if (position > 0 && position < _distance)
166+
{
167+
laneArray[notes[i].HandPosition].Add(Matrix4x4.TRS(
168+
new Vector3(notes[i].HandPosition + 0.5f, 0, position),
227169
Quaternion.identity, _noteScale));
228170
}
171+
}
229172

230-
Graphics.DrawMeshInstanced(_mesh, 0, _materials[x], noteMatrix);
173+
for (var x = 0; x < 5; x += 1)
174+
{
175+
Graphics.DrawMeshInstanced(_mesh, 0, _materials[x], laneArray[x]);
231176
}
232177
}
233178

@@ -242,30 +187,23 @@ private void RenderBeatBars(BeatBar[] beatBars, int resolution, int tickOffset)
242187
var position = Utilities.ConvertTickToPosition(beatBars[x].Position - tickOffset, resolution) *
243188
_scale;
244189

245-
if (position > _distance)
246-
{
247-
break;
248-
}
249-
250-
if (position < 0)
251-
{
252-
continue;
253-
}
254-
255-
if (x % 8 == 0)
256-
{
257-
beatBarMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity,
258-
_beatBarScaleFull));
259-
}
260-
else if (x % 2 == 0)
261-
{
262-
beatBarHalfMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity,
263-
_beatBarScaleHalf));
264-
}
265-
else
190+
if (position > 0 && position < _distance)
266191
{
267-
beatBarQuarterMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity,
268-
_beatBarScaleQuarter));
192+
if (x % 8 == 0)
193+
{
194+
beatBarMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity,
195+
_beatBarScaleFull));
196+
}
197+
else if (x % 2 == 0)
198+
{
199+
beatBarHalfMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity,
200+
_beatBarScaleHalf));
201+
}
202+
else
203+
{
204+
beatBarQuarterMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity,
205+
_beatBarScaleQuarter));
206+
}
269207
}
270208
}
271209

0 commit comments

Comments
 (0)