diff --git a/README.md b/README.md index c1deef6..f042183 100644 --- a/README.md +++ b/README.md @@ -96,26 +96,6 @@ for (var x = 0; x < waveform.Length; x += 1) _texture2D.Apply(); ``` -### `Song` - -#### `Song.FromChartFile` - -```csharp -using RhythmGameUtilities; - -var contents = File.ReadAllText("notes.chart", Encoding.UTF8); -var song = RhythmGameUtilities.Song.FromChartFile(contents); -``` - -#### `Song.FromJSON` - -```csharp -using RhythmGameUtilities; - -var json = File.ReadAllText("notes.json", Encoding.UTF8); -var song = RhythmGameUtilities.Song.FromJSON(json); -``` - ### `Parsers` Read more about `.chart` files: diff --git a/RhythmGameUtilities.Tests/SongTest.cs b/RhythmGameUtilities.Tests/SongTest.cs deleted file mode 100644 index f1ae21c..0000000 --- a/RhythmGameUtilities.Tests/SongTest.cs +++ /dev/null @@ -1,84 +0,0 @@ -using NUnit.Framework; - -namespace RhythmGameUtilities.Tests -{ - - public class SongTest - { - - [Test] - public void SongFromChartFileTest() - { - var song = Song.FromChartFile(Mocks.SONG_CHART); - - Assert.That(song.Name, Is.EqualTo("Example Song")); - Assert.That(song.Artist, Is.EqualTo("Example Artist")); - Assert.That(song.Album, Is.EqualTo("Example Album")); - Assert.That(song.Genre, Is.EqualTo("Example Genre")); - Assert.That(song.Year, Is.EqualTo(", 2021")); - Assert.That(song.Charter, Is.EqualTo("Example Charter")); - Assert.That(song.Resolution, Is.EqualTo(192)); - Assert.That(song.Difficulty, Is.EqualTo(4)); - Assert.That(song.Offset, Is.EqualTo(0.56)); - Assert.That(song.PreviewStart, Is.EqualTo(45.28)); - Assert.That(song.PreviewEnd, Is.EqualTo(75.28)); - Assert.That(song.MusicStream, Is.EqualTo("Example Song.ogg")); - Assert.That(song.Difficulties.Count, Is.EqualTo(1)); - Assert.That(song.Difficulties.ContainsKey(Difficulty.Expert), Is.True); - Assert.That(song.Difficulties[Difficulty.Expert].Length, Is.EqualTo(8)); - Assert.That(song.BPM.Count, Is.EqualTo(7)); - - Assert.That(song.ToJSON(), Is.EqualTo(Mocks.SONG_JSON)); - } - - [Test] - public void SongFromJSONTest() - { - var song = Song.FromJSON(Mocks.SONG_JSON); - - Assert.That(song.Name, Is.EqualTo("Example Song")); - Assert.That(song.Artist, Is.EqualTo("Example Artist")); - Assert.That(song.Album, Is.EqualTo("Example Album")); - Assert.That(song.Genre, Is.EqualTo("Example Genre")); - Assert.That(song.Year, Is.EqualTo(", 2021")); - Assert.That(song.Charter, Is.EqualTo("Example Charter")); - Assert.That(song.Resolution, Is.EqualTo(192)); - Assert.That(song.Difficulty, Is.EqualTo(4)); - Assert.That(song.Offset, Is.EqualTo(0.56)); - Assert.That(song.PreviewStart, Is.EqualTo(45.28)); - Assert.That(song.PreviewEnd, Is.EqualTo(75.28)); - Assert.That(song.MusicStream, Is.EqualTo("Example Song.ogg")); - Assert.That(song.Difficulties.Count, Is.EqualTo(1)); - Assert.That(song.Difficulties.ContainsKey(Difficulty.Expert), Is.True); - Assert.That(song.Difficulties[Difficulty.Expert].Length, Is.EqualTo(8)); - Assert.That(song.BPM.Count, Is.EqualTo(7)); - } - - [Test] - public void GetCurrentBPMTest() - { - var song = Song.FromChartFile(Mocks.SONG_CHART); - - Assert.That(song.GetCurrentBPM(), Is.EqualTo(88)); - Assert.That(song.GetCurrentBPM(new Note { Position = 0 }), Is.EqualTo(88)); - Assert.That(song.GetCurrentBPM(new Note { Position = 3840 }), Is.EqualTo(112)); - Assert.That(song.GetCurrentBPM(new Note { Position = 9984 }), Is.EqualTo(89)); - Assert.That(song.GetCurrentBPM(new Note { Position = 22272 }), Is.EqualTo(112)); - Assert.That(song.GetCurrentBPM(new Note { Position = 33792 }), Is.EqualTo(111)); - Assert.That(song.GetCurrentBPM(new Note { Position = 34560 }), Is.EqualTo(112)); - } - - [Test] - public void GetCurrentTimeSignatureTest() - { - var song = Song.FromChartFile(Mocks.SONG_CHART); - - Assert.That(song.GetCurrentTimeSignature(), Is.EqualTo(new[] { 4 })); - - Assert.That(song.GetCurrentTimeSignature(new Note { Position = 9984 }), - Is.EqualTo(new[] { 2, 1 })); - } - - } - -} diff --git a/RhythmGameUtilities/Structs/Song.cs b/RhythmGameUtilities/Structs/Song.cs deleted file mode 100644 index 336e8dd..0000000 --- a/RhythmGameUtilities/Structs/Song.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; - -namespace RhythmGameUtilities -{ - - public class Song - { - - [JsonIgnore] - private List _beatBars = new(); - - [JsonIgnore] - private Dictionary _sortedBPM = new(); - - /// - /// Title of the song. - /// - [JsonProperty] - public string Name { get; internal set; } - - /// - /// Artist(s) or band(s) behind the song. - /// - [JsonProperty] - public string Artist { get; internal set; } - - /// - /// Title of the album the song is featured in. - /// - [JsonProperty] - public string Album { get; internal set; } - - /// - /// Genre of the song. - /// - [JsonProperty] - public string Genre { get; internal set; } - - /// - /// Year of the song’s release.
Typically preceded by a comma and space, for example `, 2002`, to make importing - /// into GHTCP quicker. - ///
- [JsonProperty] - public string Year { get; internal set; } - - /// - /// Community member who charted the song. - /// - [JsonProperty] - public string Charter { get; internal set; } - - /// - /// (Required) Number of positional ticks between each 1/4th note in the chart. - /// - [JsonProperty] - public int Resolution { get; internal set; } - - /// - /// Estimated difficulty of the song. - /// - [JsonProperty] - public int Difficulty { get; internal set; } - - /// - /// Start time of the audio, in seconds.
A higher value makes the audio start sooner. - ///
- [JsonProperty] - public double Offset { get; internal set; } - - /// - /// Time of the song, in seconds, where the song preview should start. - /// - [JsonProperty] - public double PreviewStart { get; internal set; } - - /// - /// Time of the song, in seconds, where the song preview should end. - /// - [JsonProperty] - public double PreviewEnd { get; internal set; } - - /// - /// The main audio stream.
When other audio stems are present, this is background audio not in the other tracks - /// and/or instruments not charted. - ///
- [JsonProperty] - public string MusicStream { get; internal set; } - - [JsonProperty] - public Dictionary Lyrics { get; internal set; } - - [JsonProperty] - public Dictionary Difficulties { get; internal set; } - - [JsonProperty] - public Dictionary BPM { get; internal set; } - - [JsonProperty] - public Dictionary TimeSignatures { get; internal set; } - - [JsonProperty] - public List BeatBars - { - get - { - if (_beatBars.Count == 0) - { - _beatBars = Utilities.CalculateBeatBars(BPM); - } - - return _beatBars; - } - } - - public static Song FromChartFile(string input) - { - - var sections = Parsers.ParseSectionsFromChart(input); - - var data = sections[NamedSection.Song] - .ToDictionary(item => item.Key, x => x.Value); - - var song = new Song - { - Name = data.TryGetValue("Name", out var nameValue) ? nameValue[0] : null, - Artist = data.TryGetValue("Artist", out var artistValue) ? artistValue[0] : null, - Album = data.TryGetValue("Album", out var albumValue) ? albumValue[0] : null, - Genre = data.TryGetValue("Genre", out var genreValue) ? genreValue[0] : null, - Year = data.TryGetValue("Year", out var yearValue) ? yearValue[0] : null, - Charter = data.TryGetValue("Charter", out var charterValue) ? charterValue[0] : null, - Resolution = int.TryParse(data["Resolution"][0], out var resolutionValue) ? resolutionValue : 0, - Difficulty = int.TryParse(data["Difficulty"][0], out var difficultyValue) ? difficultyValue : 0, - Offset = - double.TryParse(data["Offset"][0], out var offsetValue) ? offsetValue : 0, - PreviewStart = - double.TryParse(data["PreviewStart"][0], out var previewStartValue) ? previewStartValue : 0, - PreviewEnd = double.TryParse(data["PreviewEnd"][0], out var previewEndValue) ? previewEndValue : 0, - MusicStream = - data.TryGetValue("MusicStream", out var musicStreamValue) ? musicStreamValue[0] : null, - Lyrics = Parsers.ParseLyricsFromChartSection(sections[NamedSection.SyncTrack]), - Difficulties = Enum.GetValues(typeof(Difficulty)) - .Cast() - .Where(difficulty => sections.ToDictionary(item => item.Key, x => x.Value) - .ContainsKey($"{difficulty}Single")) - .ToDictionary(difficulty => difficulty, - difficulty => Parsers.ParseNotesFromChartSection(sections[$"{difficulty}Single"])), - BPM = Parsers.ParseBpmFromChartSection(sections[NamedSection.SyncTrack]), - TimeSignatures = Parsers.ParseTimeSignaturesFromChartSection(sections[NamedSection.SyncTrack]) - }; - - return song; - } - - public string ToJSON() - { - return JsonConvert.SerializeObject(this); - } - - public static Song FromJSON(string input) - { - return JsonConvert.DeserializeObject(input); - } - - public int GetCurrentBPM() - { - return BPM.First().Value / 1000; - } - - public int GetCurrentBPM(Note note) - { - return BPM.Last(item => item.Key <= note.Position).Value / 1000; - } - - public int[] GetCurrentTimeSignature() - { - return TimeSignatures.First().Value; - } - - public int[] GetCurrentTimeSignature(Note note) - { - return TimeSignatures.Last(item => item.Key <= note.Position).Value; - } - - } - -} diff --git a/UnityPackage/Editor/Tests/SongTest.cs b/UnityPackage/Editor/Tests/SongTest.cs deleted file mode 100644 index f1ae21c..0000000 --- a/UnityPackage/Editor/Tests/SongTest.cs +++ /dev/null @@ -1,84 +0,0 @@ -using NUnit.Framework; - -namespace RhythmGameUtilities.Tests -{ - - public class SongTest - { - - [Test] - public void SongFromChartFileTest() - { - var song = Song.FromChartFile(Mocks.SONG_CHART); - - Assert.That(song.Name, Is.EqualTo("Example Song")); - Assert.That(song.Artist, Is.EqualTo("Example Artist")); - Assert.That(song.Album, Is.EqualTo("Example Album")); - Assert.That(song.Genre, Is.EqualTo("Example Genre")); - Assert.That(song.Year, Is.EqualTo(", 2021")); - Assert.That(song.Charter, Is.EqualTo("Example Charter")); - Assert.That(song.Resolution, Is.EqualTo(192)); - Assert.That(song.Difficulty, Is.EqualTo(4)); - Assert.That(song.Offset, Is.EqualTo(0.56)); - Assert.That(song.PreviewStart, Is.EqualTo(45.28)); - Assert.That(song.PreviewEnd, Is.EqualTo(75.28)); - Assert.That(song.MusicStream, Is.EqualTo("Example Song.ogg")); - Assert.That(song.Difficulties.Count, Is.EqualTo(1)); - Assert.That(song.Difficulties.ContainsKey(Difficulty.Expert), Is.True); - Assert.That(song.Difficulties[Difficulty.Expert].Length, Is.EqualTo(8)); - Assert.That(song.BPM.Count, Is.EqualTo(7)); - - Assert.That(song.ToJSON(), Is.EqualTo(Mocks.SONG_JSON)); - } - - [Test] - public void SongFromJSONTest() - { - var song = Song.FromJSON(Mocks.SONG_JSON); - - Assert.That(song.Name, Is.EqualTo("Example Song")); - Assert.That(song.Artist, Is.EqualTo("Example Artist")); - Assert.That(song.Album, Is.EqualTo("Example Album")); - Assert.That(song.Genre, Is.EqualTo("Example Genre")); - Assert.That(song.Year, Is.EqualTo(", 2021")); - Assert.That(song.Charter, Is.EqualTo("Example Charter")); - Assert.That(song.Resolution, Is.EqualTo(192)); - Assert.That(song.Difficulty, Is.EqualTo(4)); - Assert.That(song.Offset, Is.EqualTo(0.56)); - Assert.That(song.PreviewStart, Is.EqualTo(45.28)); - Assert.That(song.PreviewEnd, Is.EqualTo(75.28)); - Assert.That(song.MusicStream, Is.EqualTo("Example Song.ogg")); - Assert.That(song.Difficulties.Count, Is.EqualTo(1)); - Assert.That(song.Difficulties.ContainsKey(Difficulty.Expert), Is.True); - Assert.That(song.Difficulties[Difficulty.Expert].Length, Is.EqualTo(8)); - Assert.That(song.BPM.Count, Is.EqualTo(7)); - } - - [Test] - public void GetCurrentBPMTest() - { - var song = Song.FromChartFile(Mocks.SONG_CHART); - - Assert.That(song.GetCurrentBPM(), Is.EqualTo(88)); - Assert.That(song.GetCurrentBPM(new Note { Position = 0 }), Is.EqualTo(88)); - Assert.That(song.GetCurrentBPM(new Note { Position = 3840 }), Is.EqualTo(112)); - Assert.That(song.GetCurrentBPM(new Note { Position = 9984 }), Is.EqualTo(89)); - Assert.That(song.GetCurrentBPM(new Note { Position = 22272 }), Is.EqualTo(112)); - Assert.That(song.GetCurrentBPM(new Note { Position = 33792 }), Is.EqualTo(111)); - Assert.That(song.GetCurrentBPM(new Note { Position = 34560 }), Is.EqualTo(112)); - } - - [Test] - public void GetCurrentTimeSignatureTest() - { - var song = Song.FromChartFile(Mocks.SONG_CHART); - - Assert.That(song.GetCurrentTimeSignature(), Is.EqualTo(new[] { 4 })); - - Assert.That(song.GetCurrentTimeSignature(new Note { Position = 9984 }), - Is.EqualTo(new[] { 2, 1 })); - } - - } - -} diff --git a/UnityPackage/Editor/Tests/SongTest.cs.meta b/UnityPackage/Editor/Tests/SongTest.cs.meta deleted file mode 100644 index b31e82d..0000000 --- a/UnityPackage/Editor/Tests/SongTest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bac516f9e412941239d32d438b85d055 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityPackage/README.md b/UnityPackage/README.md index c1deef6..f042183 100644 --- a/UnityPackage/README.md +++ b/UnityPackage/README.md @@ -96,26 +96,6 @@ for (var x = 0; x < waveform.Length; x += 1) _texture2D.Apply(); ``` -### `Song` - -#### `Song.FromChartFile` - -```csharp -using RhythmGameUtilities; - -var contents = File.ReadAllText("notes.chart", Encoding.UTF8); -var song = RhythmGameUtilities.Song.FromChartFile(contents); -``` - -#### `Song.FromJSON` - -```csharp -using RhythmGameUtilities; - -var json = File.ReadAllText("notes.json", Encoding.UTF8); -var song = RhythmGameUtilities.Song.FromJSON(json); -``` - ### `Parsers` Read more about `.chart` files: diff --git a/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Half).mat b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Half).mat new file mode 100644 index 0000000..c055dc8 --- /dev/null +++ b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Half).mat @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Beat Bar (Half) + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_Parent: {fileID: 2100000, guid: 4f149c28b4b85433d8ccdec2b588d052, type: 2} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHAPREMULTIPLY_ON + - _GLOSSYREFLECTIONS_OFF + - _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + - _SPECULARHIGHLIGHTS_OFF + m_InvalidKeywords: + - _SURFACE_TYPE_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: [] + m_Ints: [] + m_Floats: [] + m_Colors: + - _BaseColor: {r: 0.6981132, g: 0.6981132, b: 0.6981132, a: 0.38431373} + - _Color: {r: 0.6981132, g: 0.6981132, b: 0.6981132, a: 0.38431373} + m_BuildTextureStacks: [] +--- !u!114 &1389458605193611525 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 7 diff --git a/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Half).mat.meta b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Half).mat.meta new file mode 100644 index 0000000..a8879f4 --- /dev/null +++ b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Half).mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 97e91637817d8439894205ef0ce7d1e5 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Quarter).mat b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Quarter).mat new file mode 100644 index 0000000..4321697 --- /dev/null +++ b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Quarter).mat @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Beat Bar (Quarter) + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_Parent: {fileID: 2100000, guid: 4f149c28b4b85433d8ccdec2b588d052, type: 2} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHAPREMULTIPLY_ON + - _GLOSSYREFLECTIONS_OFF + - _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + - _SPECULARHIGHLIGHTS_OFF + m_InvalidKeywords: + - _SURFACE_TYPE_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: [] + m_Ints: [] + m_Floats: [] + m_Colors: + - _BaseColor: {r: 0.6981132, g: 0.6981132, b: 0.6981132, a: 0.14901961} + - _Color: {r: 0.6981132, g: 0.6981132, b: 0.6981132, a: 0.14901961} + m_BuildTextureStacks: [] +--- !u!114 &1389458605193611525 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 7 diff --git a/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Quarter).mat.meta b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Quarter).mat.meta new file mode 100644 index 0000000..b23aa11 --- /dev/null +++ b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar (Quarter).mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d36249a89c32b470d8c6b40cd6e5e118 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityPackage/Samples~/SampleSong/Materials/Beat Bar.mat b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar.mat new file mode 100644 index 0000000..569b758 --- /dev/null +++ b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar.mat @@ -0,0 +1,142 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Beat Bar + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _ALPHAPREMULTIPLY_ON + - _GLOSSYREFLECTIONS_OFF + - _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + - _SPECULARHIGHLIGHTS_OFF + m_InvalidKeywords: + - _SURFACE_TYPE_TRANSPARENT + m_LightmapFlags: 4 + m_EnableInstancingVariants: 1 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 3000 + stringTagMap: + RenderType: Transparent + disabledShaderPasses: + - DepthOnly + - SHADOWCASTER + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 10 + - _DstBlendAlpha: 10 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _Mode: 3 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 1 + - _SpecularHighlights: 0 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 1 + - _UVSec: 0 + - _WorkflowMode: 1 + - _ZWrite: 0 + m_Colors: + - _BaseColor: {r: 0.6981132, g: 0.6981132, b: 0.6981132, a: 1} + - _Color: {r: 0.6981132, g: 0.6981132, b: 0.6981132, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] +--- !u!114 &3220555490801046827 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 7 diff --git a/UnityPackage/Samples~/SampleSong/Materials/Beat Bar.mat.meta b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar.mat.meta new file mode 100644 index 0000000..4d3be9a --- /dev/null +++ b/UnityPackage/Samples~/SampleSong/Materials/Beat Bar.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4f149c28b4b85433d8ccdec2b588d052 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityPackage/Samples~/SampleSong/Materials/Note 1.mat b/UnityPackage/Samples~/SampleSong/Materials/Note 1.mat index ab1e741..0244722 100644 --- a/UnityPackage/Samples~/SampleSong/Materials/Note 1.mat +++ b/UnityPackage/Samples~/SampleSong/Materials/Note 1.mat @@ -11,7 +11,9 @@ Material: m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} m_Parent: {fileID: 2100000, guid: 4ae981b9a0c2c447e843318a20998783, type: 2} m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] + m_ValidKeywords: + - _GLOSSYREFLECTIONS_OFF + - _SPECULARHIGHLIGHTS_OFF m_InvalidKeywords: [] m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/UnityPackage/Samples~/SampleSong/Materials/Note 2.mat b/UnityPackage/Samples~/SampleSong/Materials/Note 2.mat index 137c781..28cedc7 100644 --- a/UnityPackage/Samples~/SampleSong/Materials/Note 2.mat +++ b/UnityPackage/Samples~/SampleSong/Materials/Note 2.mat @@ -11,7 +11,9 @@ Material: m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} m_Parent: {fileID: 2100000, guid: 4ae981b9a0c2c447e843318a20998783, type: 2} m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] + m_ValidKeywords: + - _GLOSSYREFLECTIONS_OFF + - _SPECULARHIGHLIGHTS_OFF m_InvalidKeywords: [] m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/UnityPackage/Samples~/SampleSong/Materials/Note 3.mat b/UnityPackage/Samples~/SampleSong/Materials/Note 3.mat index b44ced9..b78be0c 100644 --- a/UnityPackage/Samples~/SampleSong/Materials/Note 3.mat +++ b/UnityPackage/Samples~/SampleSong/Materials/Note 3.mat @@ -11,7 +11,9 @@ Material: m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} m_Parent: {fileID: 2100000, guid: 4ae981b9a0c2c447e843318a20998783, type: 2} m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] + m_ValidKeywords: + - _GLOSSYREFLECTIONS_OFF + - _SPECULARHIGHLIGHTS_OFF m_InvalidKeywords: [] m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/UnityPackage/Samples~/SampleSong/Materials/Note.mat b/UnityPackage/Samples~/SampleSong/Materials/Note.mat index 5c00601..190b8cd 100644 --- a/UnityPackage/Samples~/SampleSong/Materials/Note.mat +++ b/UnityPackage/Samples~/SampleSong/Materials/Note.mat @@ -11,7 +11,9 @@ Material: m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} m_Parent: {fileID: 0} m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] + m_ValidKeywords: + - _GLOSSYREFLECTIONS_OFF + - _SPECULARHIGHLIGHTS_OFF m_InvalidKeywords: [] m_LightmapFlags: 4 m_EnableInstancingVariants: 1 @@ -67,13 +69,13 @@ Material: - _DstBlend: 0 - _GlossMapScale: 1 - _Glossiness: 0.5 - - _GlossyReflections: 1 + - _GlossyReflections: 0 - _Metallic: 0 - _Mode: 0 - _OcclusionStrength: 1 - _Parallax: 0.02 - _SmoothnessTextureChannel: 0 - - _SpecularHighlights: 1 + - _SpecularHighlights: 0 - _SrcBlend: 1 - _UVSec: 0 - _ZWrite: 1 diff --git a/UnityPackage/Samples~/SampleSong/Materials/Track.mat b/UnityPackage/Samples~/SampleSong/Materials/Track.mat new file mode 100644 index 0000000..aa0f528 --- /dev/null +++ b/UnityPackage/Samples~/SampleSong/Materials/Track.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Track + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _GLOSSYREFLECTIONS_OFF + - _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + - _SPECULARHIGHLIGHTS_OFF + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 1 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 1 + - _SpecularHighlights: 0 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _UVSec: 0 + - _WorkflowMode: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.16981131, g: 0.16981131, b: 0.16981131, a: 1} + - _Color: {r: 0.16981128, g: 0.16981128, b: 0.16981128, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] +--- !u!114 &1260500772416368619 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 7 diff --git a/UnityPackage/Samples~/SampleSong/Materials/Track.mat.meta b/UnityPackage/Samples~/SampleSong/Materials/Track.mat.meta new file mode 100644 index 0000000..741d005 --- /dev/null +++ b/UnityPackage/Samples~/SampleSong/Materials/Track.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a4c864fe19fd74c3fb6ece2f36cb4bdf +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityPackage/Samples~/SampleSong/Scenes/RenderSong.unity b/UnityPackage/Samples~/SampleSong/Scenes/RenderSong.unity index a7342f7..9f2d9d8 100644 --- a/UnityPackage/Samples~/SampleSong/Scenes/RenderSong.unity +++ b/UnityPackage/Samples~/SampleSong/Scenes/RenderSong.unity @@ -358,7 +358,10 @@ MonoBehaviour: _songPath: Samples/Rhythm Game Utilities/1.0.0/Sample Song/StreamingAssets/Songs/Demo 1 _mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} - _material: {fileID: 2100000, guid: 4ae981b9a0c2c447e843318a20998783, type: 2} + _trackMaterial: {fileID: 2100000, guid: a4c864fe19fd74c3fb6ece2f36cb4bdf, type: 2} + _beatBarMaterial: {fileID: 2100000, guid: 4f149c28b4b85433d8ccdec2b588d052, type: 2} + _beatBarHalfMaterial: {fileID: 2100000, guid: 97e91637817d8439894205ef0ce7d1e5, type: 2} + _beatBarQuarterMaterial: {fileID: 2100000, guid: d36249a89c32b470d8c6b40cd6e5e118, type: 2} _materials: - {fileID: 2100000, guid: 20dbc966d585d4a78b32ccec4fa43a1a, type: 2} - {fileID: 2100000, guid: 4176e88ba7b1c4bdbbe42088cf278b13, type: 2} diff --git a/UnityPackage/Samples~/SampleSong/Scripts/RenderSong.cs b/UnityPackage/Samples~/SampleSong/Scripts/RenderSong.cs index 00ad8c1..eb67452 100644 --- a/UnityPackage/Samples~/SampleSong/Scripts/RenderSong.cs +++ b/UnityPackage/Samples~/SampleSong/Scripts/RenderSong.cs @@ -1,7 +1,9 @@ +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using System.Web; using RhythmGameUtilities; using UnityEngine; using UnityEngine.Networking; @@ -16,7 +18,16 @@ public class RenderSong : MonoBehaviour private Mesh _mesh; [SerializeField] - private Material _material; + private Material _trackMaterial; + + [SerializeField] + private Material _beatBarMaterial; + + [SerializeField] + private Material _beatBarHalfMaterial; + + [SerializeField] + private Material _beatBarQuarterMaterial; [SerializeField] private Material[] _materials; @@ -30,34 +41,65 @@ public class RenderSong : MonoBehaviour [SerializeField] private float _distance = 50; - private Song _song; + private readonly Vector3 _noteScale = new(0.5f, 0.25f, 0.35f); + + private readonly Vector3 _noteScaleFlat = new(0.5f, 0.05f, 0.35f); + + private readonly Vector3 _beatBarScaleFull = new(5, 0.03f, 0.1f); + + private readonly Vector3 _beatBarScaleHalf = new(5, 0.03f, 0.05f); + + private readonly Vector3 _beatBarScaleQuarter = new(5, 0.03f, 0.01f); - private readonly Vector3 _noteScale = new(0.5f, 0.25f, 0.5f); + public int resolution { get; set; } = 192; - private readonly Vector3 _noteScaleFlat = new(0.5f, 0.05f, 0.5f); + public Dictionary bpm { get; set; } - private readonly Vector3 _beatBarScale = new(5, 0.03f, 0.03f); + public Dictionary difficulties { get; set; } - private Dictionary> _notesGroupedByHandPosition; + public Dictionary> notesGroupedByHandPosition { get; set; } + + public List beatBars { get; set; } private async void Start() { - _song = Song.FromChartFile( - await LoadTextFileFromPath( - $"file://{Path.Join(Application.dataPath, _songPath, "notes.chart")}")); + var path = Path.Join(Application.dataPath, _songPath, "notes.chart"); + + var contents = await LoadTextFileFromPath($"file://{HttpUtility.UrlPathEncode(path)}"); + + var sections = Parsers.ParseSectionsFromChart(contents); + + var metadata = Parsers.ParseMetaDataFromChartSection(sections + .First(section => section.Key == NamedSection.Song) + .Value); + + _audioSource.clip = + await LoadAudioFileFromPath( + $"file://{HttpUtility.UrlPathEncode(Path.Join(Path.GetDirectoryName(path), metadata["MusicStream"]))}"); - _audioSource.clip = await LoadAudioFileFromPath( - $"file://{Path.Join(Application.dataPath, _songPath, "song.ogg")}"); + resolution = int.Parse(metadata["Resolution"]); - var lastTick = Utilities.ConvertSecondsToTicks(_audioSource.clip.length, _song.Resolution, _song.BPM); + bpm = Parsers.ParseBpmFromChartSection(sections.First(section => section.Key == NamedSection.SyncTrack) + .Value); - _song.BPM.TryAdd(Utilities.RoundUpToTheNearestMultiplier(lastTick, _song.Resolution), _song.BPM.Last().Value); + var lastTick = Utilities.ConvertSecondsToTicks(_audioSource.clip.length, resolution, bpm); - _notesGroupedByHandPosition = _song.Difficulties[Difficulty.Expert] + bpm.TryAdd(Utilities.RoundUpToTheNearestMultiplier(lastTick, resolution), bpm.Last().Value); + + difficulties = Enum.GetValues(typeof(Difficulty)) + .Cast() + .Where(difficulty => sections.ToDictionary(item => item.Key, x => x.Value) + .ContainsKey($"{difficulty}Single")) + .ToDictionary(difficulty => difficulty, + difficulty => Parsers.ParseNotesFromChartSection(sections[$"{difficulty}Single"])); + + notesGroupedByHandPosition = difficulties[Difficulty.Expert] .Where(note => note.HandPosition < 5) .GroupBy(note => note.HandPosition) .ToDictionary(group => group.Key, group => group.ToList()); + beatBars = Utilities.CalculateBeatBars(bpm, includeHalfNotes : true); + _audioSource.Play(); } @@ -104,16 +146,45 @@ public static async Task LoadAudioFileFromPath(string path, AudioType private void Update() { - if (_song == null || _notesGroupedByHandPosition == null) + RenderTrack(); + + if (notesGroupedByHandPosition == null) { return; } - var tickOffset = Utilities.ConvertSecondsToTicks(_audioSource.time, _song.Resolution, _song.BPM); + var tickOffset = + Utilities.ConvertSecondsToTicks(_audioSource.time, resolution, bpm); + + RenderHitNotes(notesGroupedByHandPosition); - for (var x = 0; x < _notesGroupedByHandPosition.Count; x += 1) + RenderNotes(notesGroupedByHandPosition, resolution, tickOffset); + RenderBeatBars(beatBars, resolution, tickOffset); + } + + private void RenderTrack() + { + Graphics.DrawMesh(_mesh, + Matrix4x4.TRS(new Vector3(2.5f, -0.05f, _distance / 2), Quaternion.identity, + new Vector3(5f, 0.1f, _distance)), + _trackMaterial, 0); + } + + private void RenderHitNotes(Dictionary> notesGroupedByHandPosition) + { + for (var x = 0; x < notesGroupedByHandPosition.Count; x += 1) { - if (!_notesGroupedByHandPosition.ContainsKey(x)) + Graphics.DrawMesh(_mesh, + Matrix4x4.TRS(new Vector3(x + 0.5f, 0, 0), Quaternion.identity, _noteScaleFlat), + _materials[x], 0); + } + } + + private void RenderNotes(Dictionary> notesGroupedByHandPosition, int resolution, int tickOffset) + { + for (var x = 0; x < notesGroupedByHandPosition.Count; x += 1) + { + if (!notesGroupedByHandPosition.ContainsKey(x)) { continue; } @@ -123,9 +194,10 @@ private void Update() Matrix4x4.TRS(new Vector3(x + 0.5f, 0, 0), Quaternion.identity, _noteScaleFlat) }; - foreach (var note in _notesGroupedByHandPosition[x]) + for (var y = 0; y < notesGroupedByHandPosition[x].Count; y += 1) { - var position = Utilities.ConvertTickToPosition(note.Position - tickOffset, _song.Resolution) * _scale; + var position = Utilities.ConvertTickToPosition(notesGroupedByHandPosition[x][y].Position - tickOffset, + resolution) * _scale; if (position > _distance) { @@ -137,18 +209,25 @@ private void Update() continue; } - noteMatrix.Add(Matrix4x4.TRS(new Vector3(note.HandPosition + 0.5f, 0, position), + noteMatrix.Add(Matrix4x4.TRS( + new Vector3(notesGroupedByHandPosition[x][y].HandPosition + 0.5f, 0, position), Quaternion.identity, _noteScale)); } Graphics.DrawMeshInstanced(_mesh, 0, _materials[x], noteMatrix); } + } + private void RenderBeatBars(List beatBars, int resolution, int tickOffset) + { var beatBarMatrix = new List(); + var beatBarHalfMatrix = new List(); + var beatBarQuarterMatrix = new List(); - foreach (var beatBar in _song.BeatBars) + for (var x = 0; x < beatBars.Count; x += 1) { - var position = Utilities.ConvertTickToPosition(beatBar.Position - tickOffset, _song.Resolution) * _scale; + var position = Utilities.ConvertTickToPosition(beatBars[x].Position - tickOffset, resolution) * + _scale; if (position > _distance) { @@ -160,10 +239,26 @@ private void Update() continue; } - beatBarMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity, _beatBarScale)); + if (x % 8 == 0) + { + beatBarMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity, + _beatBarScaleFull)); + } + else if (x % 2 == 0) + { + beatBarHalfMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity, + _beatBarScaleHalf)); + } + else + { + beatBarQuarterMatrix.Add(Matrix4x4.TRS(new Vector3(2.5f, 0, position), Quaternion.identity, + _beatBarScaleQuarter)); + } } - Graphics.DrawMeshInstanced(_mesh, 0, _material, beatBarMatrix); + Graphics.DrawMeshInstanced(_mesh, 0, _beatBarMaterial, beatBarMatrix); + Graphics.DrawMeshInstanced(_mesh, 0, _beatBarHalfMaterial, beatBarHalfMatrix); + Graphics.DrawMeshInstanced(_mesh, 0, _beatBarQuarterMaterial, beatBarQuarterMatrix); } } diff --git a/UnityPackage/Structs/Song.cs b/UnityPackage/Structs/Song.cs deleted file mode 100644 index 336e8dd..0000000 --- a/UnityPackage/Structs/Song.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; - -namespace RhythmGameUtilities -{ - - public class Song - { - - [JsonIgnore] - private List _beatBars = new(); - - [JsonIgnore] - private Dictionary _sortedBPM = new(); - - /// - /// Title of the song. - /// - [JsonProperty] - public string Name { get; internal set; } - - /// - /// Artist(s) or band(s) behind the song. - /// - [JsonProperty] - public string Artist { get; internal set; } - - /// - /// Title of the album the song is featured in. - /// - [JsonProperty] - public string Album { get; internal set; } - - /// - /// Genre of the song. - /// - [JsonProperty] - public string Genre { get; internal set; } - - /// - /// Year of the song’s release.
Typically preceded by a comma and space, for example `, 2002`, to make importing - /// into GHTCP quicker. - ///
- [JsonProperty] - public string Year { get; internal set; } - - /// - /// Community member who charted the song. - /// - [JsonProperty] - public string Charter { get; internal set; } - - /// - /// (Required) Number of positional ticks between each 1/4th note in the chart. - /// - [JsonProperty] - public int Resolution { get; internal set; } - - /// - /// Estimated difficulty of the song. - /// - [JsonProperty] - public int Difficulty { get; internal set; } - - /// - /// Start time of the audio, in seconds.
A higher value makes the audio start sooner. - ///
- [JsonProperty] - public double Offset { get; internal set; } - - /// - /// Time of the song, in seconds, where the song preview should start. - /// - [JsonProperty] - public double PreviewStart { get; internal set; } - - /// - /// Time of the song, in seconds, where the song preview should end. - /// - [JsonProperty] - public double PreviewEnd { get; internal set; } - - /// - /// The main audio stream.
When other audio stems are present, this is background audio not in the other tracks - /// and/or instruments not charted. - ///
- [JsonProperty] - public string MusicStream { get; internal set; } - - [JsonProperty] - public Dictionary Lyrics { get; internal set; } - - [JsonProperty] - public Dictionary Difficulties { get; internal set; } - - [JsonProperty] - public Dictionary BPM { get; internal set; } - - [JsonProperty] - public Dictionary TimeSignatures { get; internal set; } - - [JsonProperty] - public List BeatBars - { - get - { - if (_beatBars.Count == 0) - { - _beatBars = Utilities.CalculateBeatBars(BPM); - } - - return _beatBars; - } - } - - public static Song FromChartFile(string input) - { - - var sections = Parsers.ParseSectionsFromChart(input); - - var data = sections[NamedSection.Song] - .ToDictionary(item => item.Key, x => x.Value); - - var song = new Song - { - Name = data.TryGetValue("Name", out var nameValue) ? nameValue[0] : null, - Artist = data.TryGetValue("Artist", out var artistValue) ? artistValue[0] : null, - Album = data.TryGetValue("Album", out var albumValue) ? albumValue[0] : null, - Genre = data.TryGetValue("Genre", out var genreValue) ? genreValue[0] : null, - Year = data.TryGetValue("Year", out var yearValue) ? yearValue[0] : null, - Charter = data.TryGetValue("Charter", out var charterValue) ? charterValue[0] : null, - Resolution = int.TryParse(data["Resolution"][0], out var resolutionValue) ? resolutionValue : 0, - Difficulty = int.TryParse(data["Difficulty"][0], out var difficultyValue) ? difficultyValue : 0, - Offset = - double.TryParse(data["Offset"][0], out var offsetValue) ? offsetValue : 0, - PreviewStart = - double.TryParse(data["PreviewStart"][0], out var previewStartValue) ? previewStartValue : 0, - PreviewEnd = double.TryParse(data["PreviewEnd"][0], out var previewEndValue) ? previewEndValue : 0, - MusicStream = - data.TryGetValue("MusicStream", out var musicStreamValue) ? musicStreamValue[0] : null, - Lyrics = Parsers.ParseLyricsFromChartSection(sections[NamedSection.SyncTrack]), - Difficulties = Enum.GetValues(typeof(Difficulty)) - .Cast() - .Where(difficulty => sections.ToDictionary(item => item.Key, x => x.Value) - .ContainsKey($"{difficulty}Single")) - .ToDictionary(difficulty => difficulty, - difficulty => Parsers.ParseNotesFromChartSection(sections[$"{difficulty}Single"])), - BPM = Parsers.ParseBpmFromChartSection(sections[NamedSection.SyncTrack]), - TimeSignatures = Parsers.ParseTimeSignaturesFromChartSection(sections[NamedSection.SyncTrack]) - }; - - return song; - } - - public string ToJSON() - { - return JsonConvert.SerializeObject(this); - } - - public static Song FromJSON(string input) - { - return JsonConvert.DeserializeObject(input); - } - - public int GetCurrentBPM() - { - return BPM.First().Value / 1000; - } - - public int GetCurrentBPM(Note note) - { - return BPM.Last(item => item.Key <= note.Position).Value / 1000; - } - - public int[] GetCurrentTimeSignature() - { - return TimeSignatures.First().Value; - } - - public int[] GetCurrentTimeSignature(Note note) - { - return TimeSignatures.Last(item => item.Key <= note.Position).Value; - } - - } - -} diff --git a/UnityPackage/Structs/Song.cs.meta b/UnityPackage/Structs/Song.cs.meta deleted file mode 100644 index 27d8815..0000000 --- a/UnityPackage/Structs/Song.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cbf292715bf1403ca2fe55b84f06c1e1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityPackage/screenshot.png b/UnityPackage/screenshot.png index 2bfd509..30a08d7 100644 Binary files a/UnityPackage/screenshot.png and b/UnityPackage/screenshot.png differ diff --git a/includes/RhythmGameUtilities/Structs/Song.h b/includes/RhythmGameUtilities/Structs/Song.h deleted file mode 100644 index e82a165..0000000 --- a/includes/RhythmGameUtilities/Structs/Song.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include - -#include "RhythmGameUtilities/Enums/Difficulty.h" -#include "RhythmGameUtilities/Structs/BeatBar.h" -#include "RhythmGameUtilities/Structs/Note.h" - -namespace RhythmGameUtilities -{ - -struct Song -{ - - // Title of the song. - std::string Name; - - // Artist(s) or band(s) behind the song. - std::string Artist; - - // Title of the album the song is featured in. - std::string Album; - - // Genre of the song. - std::string Genre; - - // Year of the song’s release.
Typically preceded by a comma and space, - // for example `, 2002`, to make importing into GHTCP quicker. - std::string Year; - - // Community member who charted the song. - std::string Charter; - - // (Required) Number of positional ticks between each 1/4th note in the - // chart. - int Resolution; - - // Estimated difficulty of the song. - int Difficulty; - - // Start time of the audio, in seconds.
A higher value makes the audio - // start sooner. - double Offset; - - // Time of the song, in seconds, where the song preview should start. - double PreviewStart; - - // Time of the song, in seconds, where the song preview should end. - double PreviewEnd; - - // The main audio stream.
When other audio stems are present, this is - // background audio not in the other tracks and/or instruments not charted. - std::string MusicStream; - - std::map Lyrics; - - std::map> Difficulties; - - std::map BPM; - - std::map> TimeSignatures; - - std::vector BeatBars; -}; - -} // namespace RhythmGameUtilities diff --git a/screenshot.png b/screenshot.png index 2bfd509..30a08d7 100644 Binary files a/screenshot.png and b/screenshot.png differ