diff --git a/Assets/Resources/Sfx/metronome.ogg b/Assets/Resources/Sfx/metronome.ogg new file mode 100644 index 000000000..a18a62c3b Binary files /dev/null and b/Assets/Resources/Sfx/metronome.ogg differ diff --git a/Assets/Resources/Sfx/metronome.ogg.meta b/Assets/Resources/Sfx/metronome.ogg.meta new file mode 100644 index 000000000..8fbd89f74 --- /dev/null +++ b/Assets/Resources/Sfx/metronome.ogg.meta @@ -0,0 +1,22 @@ +fileFormatVersion: 2 +guid: a7fb99219f9c43649a79cc8a86ab4c34 +AudioImporter: + externalObjects: {} + serializedVersion: 6 + defaultSettings: + loadType: 0 + sampleRateSetting: 0 + sampleRateOverride: 44100 + compressionFormat: 1 + quality: 1 + conversionMode: 0 + platformSettingOverrides: {} + forceToMono: 0 + normalize: 1 + preloadAudioData: 1 + loadInBackground: 0 + ambisonic: 0 + 3D: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Sprites/Editor/ui/button.png b/Assets/Resources/Sprites/Editor/ui/button.png new file mode 100644 index 000000000..08a13d555 Binary files /dev/null and b/Assets/Resources/Sprites/Editor/ui/button.png differ diff --git a/Assets/Resources/Sprites/Editor/ui/button.png.meta b/Assets/Resources/Sprites/Editor/ui/button.png.meta new file mode 100644 index 000000000..ff6e63b53 --- /dev/null +++ b/Assets/Resources/Sprites/Editor/ui/button.png.meta @@ -0,0 +1,96 @@ +fileFormatVersion: 2 +guid: 77703dfffd29ca6439338d6adfc62c9b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 30, y: 30, z: 30, w: 30} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Sprites/Editor/ui/metronome.png b/Assets/Resources/Sprites/Editor/ui/metronome.png index a50ba7c41..73e18155b 100644 Binary files a/Assets/Resources/Sprites/Editor/ui/metronome.png and b/Assets/Resources/Sprites/Editor/ui/metronome.png differ diff --git a/Assets/Scenes/Editor.unity b/Assets/Scenes/Editor.unity index 3d412f17e..0bd0cb68e 100644 --- a/Assets/Scenes/Editor.unity +++ b/Assets/Scenes/Editor.unity @@ -226,8 +226,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 + m_Sprite: {fileID: 21300000, guid: 77703dfffd29ca6439338d6adfc62c9b, type: 3} + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -235,7 +235,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 + m_PixelsPerUnitMultiplier: 10 --- !u!222 &9435784 CanvasRenderer: m_ObjectHideFlags: 0 @@ -556,8 +556,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 + m_Sprite: {fileID: 21300000, guid: 77703dfffd29ca6439338d6adfc62c9b, type: 3} + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -565,7 +565,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 + m_PixelsPerUnitMultiplier: 10 --- !u!222 &129013736 CanvasRenderer: m_ObjectHideFlags: 0 @@ -731,7 +731,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} - m_Color: {r: 0.8431373, g: 0.62352943, b: 0.32941177, a: 1} + m_Color: {r: 0, g: 0.62352943, b: 0.77647066, a: 1} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 @@ -2825,8 +2825,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 + m_Sprite: {fileID: 21300000, guid: 77703dfffd29ca6439338d6adfc62c9b, type: 3} + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -2834,7 +2834,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 + m_PixelsPerUnitMultiplier: 10 --- !u!222 &678553528 CanvasRenderer: m_ObjectHideFlags: 0 @@ -5782,8 +5782,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 + m_Sprite: {fileID: 21300000, guid: 77703dfffd29ca6439338d6adfc62c9b, type: 3} + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -5791,7 +5791,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 + m_PixelsPerUnitMultiplier: 10 --- !u!222 &1345846033 CanvasRenderer: m_ObjectHideFlags: 0 @@ -5930,8 +5930,8 @@ MonoBehaviour: GridGameSelector: {fileID: 1154875943} Timeline: {fileID: 1861169747} NewBTN: {fileID: 1683100750} - OpenBTN: {fileID: 0} - SaveBTN: {fileID: 0} + OpenBTN: {fileID: 1665554291} + SaveBTN: {fileID: 678553526} --- !u!114 &1423699438 MonoBehaviour: m_ObjectHideFlags: 0 @@ -5944,8 +5944,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: f86858990a87c764892672104bdaef1f, type: 3} m_Name: m_EditorClassIdentifier: - level: {fileID: 4900000, guid: cbe1a43c8ddc790498fde2e01e66d23e, type: 3} - music: {fileID: 8300000, guid: 51af38323954a8d44874780ba4577fb4, type: 3} + level: {fileID: 4900000, guid: 4b7512c586e16a847a5b8490bf35e852, type: 3} + music: {fileID: 0} debugUI: 0 playOnStart: 0 editor: 1 @@ -6733,8 +6733,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 + m_Sprite: {fileID: 21300000, guid: 77703dfffd29ca6439338d6adfc62c9b, type: 3} + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -6742,7 +6742,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 + m_PixelsPerUnitMultiplier: 10 --- !u!222 &1665554293 CanvasRenderer: m_ObjectHideFlags: 0 @@ -6973,8 +6973,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 + m_Sprite: {fileID: 21300000, guid: 77703dfffd29ca6439338d6adfc62c9b, type: 3} + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -6982,7 +6982,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 + m_PixelsPerUnitMultiplier: 10 --- !u!222 &1683100752 CanvasRenderer: m_ObjectHideFlags: 0 @@ -7374,8 +7374,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 + m_Sprite: {fileID: 21300000, guid: 77703dfffd29ca6439338d6adfc62c9b, type: 3} + m_Type: 1 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -7383,7 +7383,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 + m_PixelsPerUnitMultiplier: 10 --- !u!222 &1783491361 CanvasRenderer: m_ObjectHideFlags: 0 @@ -7634,6 +7634,7 @@ MonoBehaviour: SongPos: {fileID: 1567318397} eventObjs: [] LayerCount: 4 + metronomeEnabled: 0 TimelineSlider: {fileID: 770589360} TimelinePlaybackBeat: {fileID: 117889364} TimelineContent: {fileID: 1852819573} diff --git a/Assets/Scripts/Conductor.cs b/Assets/Scripts/Conductor.cs index 3d1c76ec9..0a77ad78f 100644 --- a/Assets/Scripts/Conductor.cs +++ b/Assets/Scripts/Conductor.cs @@ -35,9 +35,18 @@ namespace RhythmHeavenMania // Conductor instance public static Conductor instance; + // Conductor is currently playing song public bool isPlaying; + + // Conductor is currently paused, but not fully stopped public bool isPaused; + // Last reported beat based on song position + private float lastReportedBeat = 0f; + + // Metronome tick sound enabled + public bool metronome = false; + // private AudioDspTimeKeeper timeKeeper; void Awake() @@ -101,13 +110,6 @@ namespace RhythmHeavenMania musicSource.Stop(); } - /*public void SetTime(float startBeat) - { - musicSource.time = GetSongPosFromBeat(startBeat); - songPositionInBeats = musicSource.time / secPerBeat; - GameManager.instance.SetCurrentEventToClosest(songPositionInBeats); - }*/ - public void Update() { if (isPlaying) @@ -117,6 +119,19 @@ namespace RhythmHeavenMania songPosition = time - firstBeatOffset; songPositionInBeats = songPosition / secPerBeat; + + if (metronome) + { + if (songPosition > lastReportedBeat + secPerBeat) + { + RhythmHeavenMania.Util.Jukebox.PlayOneShot("metronome"); + lastReportedBeat = (songPosition - (songPosition % secPerBeat)); + } + else if (songPosition <= lastReportedBeat) + { + lastReportedBeat = (songPosition - (songPosition % secPerBeat)); + } + } } } diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index ac0cf2774..83f070cf7 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -105,25 +105,18 @@ namespace RhythmHeavenMania // GameManager entities should ALWAYS execute before gameplay entities for (int i = 0; i < gameManagerEntities.Count; i++) { - var gameManagerEntity = gameManagerEntities[i]; - if ((gameManagerEntity.beat + eventCaller.GetGameAction(eventCaller.GetMinigame(gameManagerEntity.datamodel.Split(0)), gameManagerEntity.datamodel.Split(1)).defaultLength) > Conductor.instance.songPositionInBeats) - { - eventCaller.CallEvent(gameManagerEntities[i].datamodel); - } + eventCaller.CallEvent(gameManagerEntities[i].datamodel); } for (int i = 0; i < entitesAtSameBeat.Count; i++) { var entity = entitesAtSameBeat[i]; - if ((entity.beat + eventCaller.GetGameAction(eventCaller.GetMinigame(entity.datamodel.Split(0)), entity.datamodel.Split(1)).defaultLength) > Conductor.instance.songPositionInBeats) + // if game isn't loaded, preload game so whatever event that would be called will still run outside if needed + if (entitesAtSameBeat[i].datamodel.Split('/')[0] != currentGame && !preloadedGames.Contains(preloadedGames.Find(c => c.name == entitesAtSameBeat[i].datamodel.Split('/')[0]))) { - // if game isn't loaded, preload game so whatever event that would be called will still run outside if needed - if (entitesAtSameBeat[i].datamodel.Split('/')[0] != currentGame && !preloadedGames.Contains(preloadedGames.Find(c => c.name == entitesAtSameBeat[i].datamodel.Split('/')[0]))) - { - PreloadGame(entitesAtSameBeat[i].datamodel.Split('/')[0]); - } - eventCaller.CallEvent(entitesAtSameBeat[i].datamodel); + PreloadGame(entitesAtSameBeat[i].datamodel.Split('/')[0]); } + eventCaller.CallEvent(entitesAtSameBeat[i].datamodel); } currentEvent += entitesAtSameBeat.Count + gameManagerEntities.Count; @@ -183,16 +176,17 @@ namespace RhythmHeavenMania currentEvent = entities.IndexOf(Mathp.GetClosestInList(entities, beat)); - string newGame = Beatmap.entities[currentEvent].datamodel.Split('/')[0]; + var gameSwitchs = Beatmap.entities.FindAll(c => c.datamodel.Split(1) == "switchGame" && c.beat <= beat); - if (Beatmap.entities[currentEvent].datamodel.Split('/')[1] != "switchGame") + string newGame = Beatmap.entities[currentEvent].datamodel.Split(0); + + if (gameSwitchs.Count > 0) { - if (newGame == "gameManager") - { - // holy shit - newGame = Beatmap.entities[entities.IndexOf(Mathp.GetClosestInList(Beatmap.entities.FindAll(c => c.datamodel != "gameManager" && c.beat < Conductor.instance.songPositionInBeats).ToList().Select(c => c.beat).ToList(), beat))].datamodel.Split('/')[0]; - } + newGame = gameSwitchs[gameSwitchs.IndexOf(gameSwitchs.Find(c => c.beat == Mathp.GetClosestInList(gameSwitchs.Select(c => c.beat).ToList(), beat)))].datamodel.Split(2); + } + if (Beatmap.entities[currentEvent].datamodel.Split(1) != "switchGame" && Beatmap.entities[currentEvent].datamodel.Split(0) != "gameManager") + { SetGame(newGame); } } @@ -202,8 +196,12 @@ namespace RhythmHeavenMania public void SwitchGame(string game) { - if (currentGameSwitchIE != null) StopCoroutine(currentGameSwitchIE); - currentGameSwitchIE = StartCoroutine(SwitchGameIE(game)); + if (game != currentGame) + { + if (currentGameSwitchIE != null) + StopCoroutine(currentGameSwitchIE); + currentGameSwitchIE = StartCoroutine(SwitchGameIE(game)); + } } IEnumerator SwitchGameIE(string game) @@ -212,7 +210,7 @@ namespace RhythmHeavenMania SetGame(game); - yield return new WaitForSeconds(0.1666f); + yield return new WaitForSeconds(0.1f); this.GetComponent().enabled = false; } diff --git a/Assets/Scripts/LevelEditor/Timeline.cs b/Assets/Scripts/LevelEditor/Timeline.cs index a0a084bb0..981a6377f 100644 --- a/Assets/Scripts/LevelEditor/Timeline.cs +++ b/Assets/Scripts/LevelEditor/Timeline.cs @@ -20,6 +20,7 @@ namespace RhythmHeavenMania.Editor public List eventObjs = new List(); private bool lastFrameDrag; public int LayerCount = 4; + public bool metronomeEnabled; [Header("Timeline Components")] [SerializeField] private RectTransform TimelineSlider; @@ -67,6 +68,19 @@ namespace RhythmHeavenMania.Editor }); PauseBTN.onClick.AddListener(delegate { PlayCheck(false); }); StopBTN.onClick.AddListener(delegate { PlayCheck(true); }); + MetronomeBTN.onClick.AddListener(delegate + { + if (!Conductor.instance.metronome) + { + MetronomeBTN.transform.GetChild(0).GetComponent().color = "009FC6".Hex2RGB(); + Conductor.instance.metronome = true; + } + else + { + MetronomeBTN.transform.GetChild(0).GetComponent().color = Color.gray; + Conductor.instance.metronome = false; + } + }); Tooltip.instance.AddTooltip(PlayBTN.gameObject, "Play [Space]"); Tooltip.instance.AddTooltip(PauseBTN.gameObject, "Pause [Shift + Space]"); @@ -74,6 +88,7 @@ namespace RhythmHeavenMania.Editor Tooltip.instance.AddTooltip(MetronomeBTN.gameObject, "Metronome"); SetTimeButtonColors(true, false, false); + MetronomeBTN.transform.GetChild(0).GetComponent().color = Color.gray; } #endregion