diff --git a/Assets/Scripts/Common/SuperScroll.cs b/Assets/Scripts/Common/SuperScroll.cs index 574817e4..9e428c6f 100644 --- a/Assets/Scripts/Common/SuperScroll.cs +++ b/Assets/Scripts/Common/SuperScroll.cs @@ -51,7 +51,7 @@ namespace HeavenStudio.Common _renderer.material.mainTextureOffset = new Vector2(NormalizedX, -NormalizedY) * Tile; if (AutoScroll) { - float songPos = Conductor.instance.songPositionInBeats/100; + float songPos = Conductor.instance.unswungSongPositionInBeats/100; NormalizedX = songPos*AutoScrollX; NormalizedY = songPos*AutoScrollY; } diff --git a/Assets/Scripts/Conductor.cs b/Assets/Scripts/Conductor.cs index 1ab571ab..4f2300f9 100644 --- a/Assets/Scripts/Conductor.cs +++ b/Assets/Scripts/Conductor.cs @@ -167,7 +167,9 @@ namespace HeavenStudio SeekMusicToTime(startPos, offset); + songPos = startPos; songPosBeat = GetBeatFromSongPos(time); + songPositionInBeatsAsDouble = GetSwungBeat(songPosBeat); gameManager.SetCurrentEventToClosest(beat, true); } diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 57c34e61..237e174f 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -181,15 +181,13 @@ namespace HeavenStudio if (!preLoaded) { - if (Beatmap.Entities.Count >= 1) + if (Beatmap.Entities.Count == 0) { - string game = Beatmap.Entities[0].datamodel.Split(0); - SetCurrentGame(game); - StartCoroutine(WaitAndSetGame(game)); + SetGame("noGame"); } else { - SetGame("noGame"); + SetCurrentEventToClosest(0, true); } } @@ -380,7 +378,7 @@ namespace HeavenStudio inf = GetGameInfo(gameName); if (inf != null && !(inf.inferred || inf.fxOnly)) { - if (inf.usesAssetBundle && !(inf.AssetsLoaded || inf.AlreadyLoading)) + if (inf.UsesAssetBundle && !(inf.AssetsLoaded || inf.AlreadyLoading)) { gamesToPreload.Add(inf); Debug.Log($"ASYNC loading assetbundles for game {gameName}"); @@ -409,7 +407,7 @@ namespace HeavenStudio inf = GetGameInfo(gameName); if (inf != null && !(inf.inferred || inf.fxOnly)) { - if (inf.usesAssetBundle && !inf.AssetsLoaded) + if (inf.UsesAssetBundle && !inf.AssetsLoaded) { gamesToPreload.Add(inf); Debug.Log($"ASYNC loading assetbundles for game {gameName}"); @@ -445,13 +443,6 @@ namespace HeavenStudio foreach (RiqEntity entity in entitiesInRange) { - string gameName = entity.datamodel.Split('/')[0]; - var inf = GetGameInfo(gameName); - if (inf != null && inf.usesAssetBundle && inf.AssetsLoaded && !inf.SequencesPreloaded) - { - // Debug.Log($"Preparing game {gameName}"); - PreloadGameSequences(gameName); - } eventCaller.CallPreEvent(entity); currentPreSequence++; } @@ -579,7 +570,7 @@ namespace HeavenStudio foreach (RiqEntity entity in entitiesInRange) { - // if game isn't loaded, preload game so whatever event that would be called will still run outside if needed + // if game isn't loaded, run inactive event if (entity.datamodel.Split('/')[0] != currentGame) { eventCaller.CallEvent(entity, false); @@ -628,13 +619,17 @@ namespace HeavenStudio { if (string.IsNullOrEmpty(name)) return; Sound sound; - if (game == "common") { + if (game == "common") + { sound = SoundByte.PlayOneShot(name, beat, pitch, volume, looping, null, (offset / 1000f)); - } else { + } + else + { SoundByte.PreloadGameAudioClips(game); sound = SoundByte.PlayOneShotGame(game + "/" + name, beat, pitch, volume, looping, true, (offset / 1000f)); } - if (looping) { + if (looping) + { BeatAction.New(null, new() { new(beat + length, () => sound.KillLoop(0)), }); @@ -644,7 +639,8 @@ namespace HeavenStudio public void PlayAnimationArbitrary(string animator, string animation, float scale) { Transform animTrans = minigameObj.transform.Find(animator); - if (animTrans != null && animTrans.TryGetComponent(out Animator anim)) { + if (animTrans != null && animTrans.TryGetComponent(out Animator anim)) + { anim.DoScaledAnimationAsync(animation, scale); } } @@ -1020,17 +1016,12 @@ namespace HeavenStudio if (canPreload) { Minigames.Minigame inf = GetGameInfo(newGame); - if (inf != null && inf.usesAssetBundle && !inf.AssetsLoaded) + if (inf != null && inf.UsesAssetBundle && !inf.AssetsLoaded) { preload.Add(inf); } - StartCoroutine(WaitAndSetGame(newGame)); } - else - { - SetGame(newGame); - } - SetCurrentGame(newGame); + StartCoroutine(WaitAndSetGame(newGame)); } List allEnds = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "end" }); @@ -1099,6 +1090,13 @@ namespace HeavenStudio #endregion + /// + /// While playing a chart, switches the currently active game + /// Should only be called by chart entities + /// + /// name of the game to switch to + /// beat of the chart entity calling the switch + /// hide the screen during the switch public void SwitchGame(string game, double beat, bool flash) { if (game != currentGame) @@ -1142,11 +1140,16 @@ namespace HeavenStudio SetAmbientGlowToCurrentMinigameColor(); } + /// + /// Immediately sets the current minigame to the specified game + /// + /// + /// private void SetGame(string game, bool useMinigameColor = true) { ResetCamera(); // resetting camera before setting new minigame so minigames can set camera values in their awake call - Rasmus - GameObject prefab = GetGame(game); + GameObject prefab = GetGamePrefab(game); if (prefab == null) return; Destroy(minigameObj); @@ -1166,13 +1169,13 @@ namespace HeavenStudio SetCurrentGame(game, useMinigameColor); } - public void DestroyGame() - { - SoundByte.UnloadAudioClips(); - SetGame("noGame"); - } - string currentGameRequest = null; + /// + /// Waits for a given game to preload, then sets it as the current game + /// + /// + /// + /// private IEnumerator WaitAndSetGame(string game, bool useMinigameColor = true) { if (game == currentGameRequest) @@ -1181,7 +1184,7 @@ namespace HeavenStudio } currentGameRequest = game; var inf = GetGameInfo(game); - if (inf != null && inf.usesAssetBundle) + if (inf != null && inf.UsesAssetBundle) { if (!(inf.AssetsLoaded || inf.AlreadyLoading)) { @@ -1199,16 +1202,18 @@ namespace HeavenStudio } } - public void PreloadGameSequences(string game) + public void DestroyGame() { - var gameInfo = GetGameInfo(game); - //load the games' sound sequences - // TODO: sound sequences sould be stored in a ScriptableObject - if (gameInfo != null && gameInfo.LoadedSoundSequences == null) - gameInfo.LoadedSoundSequences = GetGame(game).GetComponent().SoundSequences; + SoundByte.UnloadAudioClips(); + SetGame("noGame"); } - public GameObject GetGame(string name) + /// + /// Get the game prefab for a given game name + /// + /// + /// + public GameObject GetGamePrefab(string name) { if (name is null or "" or "noGame") { @@ -1242,29 +1247,21 @@ namespace HeavenStudio } GameObject prefab; - if (gameInfo.usesAssetBundle) + if (gameInfo.UsesAssetBundle) { //game is packed in an assetbundle, load from that instead if (gameInfo.AssetsLoaded && gameInfo.LoadedPrefab != null) return gameInfo.LoadedPrefab; - // couldn't load cached prefab, try loading from assetbundle - try + // couldn't load cached prefab, try loading from resources (usually indev games with mispacked assetbundles) + Debug.LogWarning($"Failed to load prefab for game {name} from assetbundle, trying Resources..."); + prefab = Resources.Load($"Games/{name}"); + if (prefab != null) { - Debug.LogWarning($"Game prefab wasn't cached, loading from assetbundle for game {name}"); - return gameInfo.LoadGamePrefab(); + return prefab; } - catch (Exception e) + else { - Debug.LogWarning($"Failed to load assetbundle for game {name}, using sync loading: {e.Message}"); - prefab = Resources.Load($"Games/{name}"); - if (prefab != null) - { - return prefab; - } - else - { - Debug.LogWarning($"Game {name} not found, using noGame"); - return Resources.Load($"Games/noGame"); - } + Debug.LogWarning($"Game {name} not found, using noGame"); + return Resources.Load($"Games/noGame"); } } // games with no assetbundle (usually indev games) @@ -1293,10 +1290,13 @@ namespace HeavenStudio public bool TryGetMinigame(out T mg) where T : Minigame { - if (minigame is T tempMinigame) { + if (minigame is T tempMinigame) + { mg = tempMinigame; return true; - } else { + } + else + { mg = null; return false; } diff --git a/Assets/Scripts/LevelEditor/Commands/Block.cs b/Assets/Scripts/LevelEditor/Commands/Block.cs index 23a3b156..37b5a157 100644 --- a/Assets/Scripts/LevelEditor/Commands/Block.cs +++ b/Assets/Scripts/LevelEditor/Commands/Block.cs @@ -220,7 +220,7 @@ namespace HeavenStudio.Editor.Commands for (var i = 0; i < original.Count; i++) { var entity = original[i].DeepCopy(); - entity.beat = Conductor.instance.songPositionInBeatsAsDouble + (entity.beat - firstEntityBeat); + entity.beat = Timeline.instance.PlaybackBeat + (entity.beat - firstEntityBeat); entityIds.Add(Guid.NewGuid()); pasteEntityData.Add(entity); diff --git a/Assets/Scripts/LevelEditor/Timeline/Timeline.cs b/Assets/Scripts/LevelEditor/Timeline/Timeline.cs index b8374e5c..d393ca8b 100644 --- a/Assets/Scripts/LevelEditor/Timeline/Timeline.cs +++ b/Assets/Scripts/LevelEditor/Timeline/Timeline.cs @@ -48,7 +48,7 @@ namespace HeavenStudio.Editor.Track private Vector2 relativeMousePos; public Vector2 RelativeMousePos => relativeMousePos; - public float PlaybackBeat = 0.0f; + public double PlaybackBeat = 0d; public static float SnapInterval() { return instance.snapInterval; } @@ -392,9 +392,9 @@ namespace HeavenStudio.Editor.Track if (MouseInTimeline) MouseInTimeline = RectTransformUtility.RectangleContainsScreenPoint(TimelineScroll.viewport, Input.mousePosition, Editor.instance.EditorCamera); - + PlaybackSpeed.interactable = !Conductor.instance.isPaused; - + foreach (var rect in GameObject.FindGameObjectsWithTag("BlocksEditor")) { if (!rect.activeInHierarchy) continue; @@ -420,19 +420,19 @@ namespace HeavenStudio.Editor.Track } else { - SongBeat.text = $"Beat {string.Format("{0:0.000}", cond.songPositionInBeats)}"; + SongBeat.text = $"Beat {string.Format("{0:0.000}", cond.songPositionInBeatsAsDouble)}"; SongPos.text = FormatTime(cond.songPositionAsDouble); } // Metronome animation { - var rectTransform = MetronomeBTN.transform.GetChild(1).GetComponent(); - var rot = 0.0f; - if (Conductor.instance.metronome) + RectTransform rectTransform = MetronomeBTN.transform.GetChild(1).GetComponent(); + float rot = 0f; + if (cond.metronome) { - var startBeat = Mathf.FloorToInt(Conductor.instance.songPositionInBeats - 0.5f); - var nm = Conductor.instance.GetLoopPositionFromBeat(0.5f, 1f, ignoreSwing: false); - var loop = (startBeat % 2 == 0) ? Mathf.SmoothStep(-1.1f, 1f, nm) : Mathf.SmoothStep(1f, -1f, nm); + int startBeat = (int)Math.Floor(cond.songPositionInBeats - 0.5); + float nm = cond.GetLoopPositionFromBeat(0.5f, 1f, ignoreSwing: false); + float loop = (startBeat % 2 == 0) ? Mathf.SmoothStep(-1.1f, 1f, nm) : Mathf.SmoothStep(1f, -1f, nm); rot = loop * 45f; } @@ -631,12 +631,12 @@ namespace HeavenStudio.Editor.Track } } - public void Play(bool fromStart, float time) + public void Play(bool fromStart, double time) { GameManager.instance.SafePlay(time, 0, false); if (!Conductor.instance.isPaused) { - TimelineSongPosLineRef.transform.localPosition = new Vector3(time * PixelsPerBeat, TimelineSongPosLineRef.transform.localPosition.y); + TimelineSongPosLineRef.transform.localPosition = new Vector3((float)time * PixelsPerBeat, TimelineSongPosLineRef.transform.localPosition.y); } SetTimeButtonColors(false, true, true); @@ -649,7 +649,7 @@ namespace HeavenStudio.Editor.Track SetTimeButtonColors(true, false, true); } - public void Stop(float time) + public void Stop(double time) { if (TimelineSongPosLineRef != null) TimelineSongPosLineRef.gameObject.SetActive(false); @@ -840,7 +840,8 @@ namespace HeavenStudio.Editor.Track { for (int i = 0; i < ep.Count; i++) { - object returnVal = ep[i].parameter switch { + object returnVal = ep[i].parameter switch + { EntityTypes.Integer intVal => intVal.val, EntityTypes.Note noteVal => noteVal.val, EntityTypes.Float floatVal => floatVal.val, @@ -850,7 +851,8 @@ namespace HeavenStudio.Editor.Track _ => ep[i].parameter, }; - if (returnVal.GetType().IsEnum) { + if (returnVal.GetType().IsEnum) + { returnVal = (int)ep[i].parameter; } @@ -907,8 +909,10 @@ namespace HeavenStudio.Editor.Track { var newEntity = entity.DeepCopy(); // there's gotta be a better way to do this. i just don't know how... -AJ - foreach ((var key, var value) in new Dictionary(newEntity.dynamicData)) { - if (value is EntityTypes.DropdownObj dd) { + foreach ((var key, var value) in new Dictionary(newEntity.dynamicData)) + { + if (value is EntityTypes.DropdownObj dd) + { newEntity[key] = new EntityTypes.DropdownObj(dd.value, dd.Values); } } diff --git a/Assets/Scripts/Minigames.cs b/Assets/Scripts/Minigames.cs index 0e527195..24114af4 100644 --- a/Assets/Scripts/Minigames.cs +++ b/Assets/Scripts/Minigames.cs @@ -384,26 +384,26 @@ namespace HeavenStudio public List supportedLocales; public bool inferred; - public bool usesAssetBundle => wantAssetBundle is not null or ""; - public bool hasLocales => supportedLocales.Count > 0; - public bool AssetsLoaded => ((hasLocales && localeLoaded && currentLoadedLocale == defaultLocale) || (!hasLocales)) && commonLoaded && (!loadingPrefab) && loadComplete; + public bool UsesAssetBundle => (wantAssetBundle is not null or "") && (!badBundle); + public bool HasLocales => supportedLocales.Count > 0; + public bool AssetsLoaded => (!badBundle) && ((HasLocales && audioLoaded && currentLoadedLocale == defaultLocale) || (!HasLocales)) && resourcesLoaded && loadComplete; public bool AlreadyLoading => alreadyLoading; - public bool LoadingPrefab => loadingPrefab; - + public bool SequencesPreloaded => soundSequences != null; public string LoadableName => inferred ? "noGame" : name; public GameObject LoadedPrefab => loadedPrefab; - private AssetBundle bundleCommon = null; - private bool commonLoaded = false; - private bool commonPreloaded = false; private string currentLoadedLocale = ""; - private AssetBundle bundleLocalized = null; - private bool localeLoaded = false; - private bool localePreloaded = false; + private AssetBundle bundleResources = null; + private bool resourcesLoaded = false; + private bool resourcesPreloaded = false; + private AssetBundle bundleAudio = null; + private bool audioLoaded = false; + private bool audioPreloaded = false; private GameObject loadedPrefab = null; + private bool badBundle = false; + // eventually implement secondary assetbundles for localization instead of one "common" and one "locale" - bool loadingPrefab = false; bool loadComplete = false; private SoundSequence.SequenceKeyValue[] soundSequences = null; @@ -452,114 +452,132 @@ namespace HeavenStudio this.splitColorR = splitColorR; } - public AssetBundle GetLocalizedAssetBundle() - { - if (bundleLocalized != null && !localeLoaded) - { - bundleLocalized.Unload(true); - bundleLocalized = null; - localeLoaded = false; - localePreloaded = false; - } - if (!hasLocales) return null; - if (!usesAssetBundle) return null; - if (bundleLocalized == null || currentLoadedLocale != defaultLocale) //TEMPORARY: use the game's default locale until we add localization support - { - if (localeLoaded) return bundleLocalized; - // TODO: try/catch for missing assetbundles - currentLoadedLocale = defaultLocale; - bundleLocalized = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/locale." + defaultLocale)); - localeLoaded = true; - } - return bundleLocalized; - } - - public AssetBundle GetCommonAssetBundle() - { - if (bundleCommon != null && !commonLoaded) - { - bundleCommon.Unload(true); - bundleCommon = null; - commonLoaded = false; - commonPreloaded = false; - } - if (commonLoaded) return bundleCommon; - if (!usesAssetBundle) return null; - if (bundleCommon == null) - { - // TODO: try/catch for missing assetbundles - bundleCommon = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/common")); - commonLoaded = true; - } - return bundleCommon; - } - bool alreadyLoading = false; public async UniTaskVoid LoadAssetsAsync() { - if (alreadyLoading || AssetsLoaded || !usesAssetBundle) return; + if (alreadyLoading || AssetsLoaded || !UsesAssetBundle) return; loadComplete = false; alreadyLoading = true; - loadingPrefab = true; - await UniTask.WhenAll(LoadCommonAssetBundleAsync(), LoadLocalizedAssetBundleAsync()); - await UniTask.WhenAll(LoadGamePrefabAsync(), LoadCommonAudioClips(), LoadLocalizedAudioClips()); + await UniTask.WhenAll(LoadResourcesAssetBundleAsync(), LoadAudioAssetBundleAsync()); + if (badBundle) + { + Debug.LogWarning($"Bad bundle for {name}"); + alreadyLoading = false; + loadComplete = true; + return; + } + await UniTask.WhenAll(LoadGamePrefabAsync(), PrepareResources(), PrepareAudio()); SoundByte.PreloadGameAudioClips(this); alreadyLoading = false; loadComplete = true; } - public async UniTask LoadCommonAssetBundleAsync() + public AssetBundle GetAudioAssetBundle() { - if (bundleCommon != null && !commonLoaded) + if (bundleAudio != null && !audioLoaded) { - await bundleCommon.UnloadAsync(true); - bundleCommon = null; - commonLoaded = false; - commonPreloaded = false; + bundleAudio.Unload(true); + bundleAudio = null; + audioLoaded = false; + audioPreloaded = false; } - - if (commonPreloaded || commonLoaded) return; - commonPreloaded = true; - if (!usesAssetBundle) return; - if (bundleCommon != null) return; - - AssetBundle bundle = await AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/common")).ToUniTask(timing: PlayerLoopTiming.PreLateUpdate); - - bundleCommon = bundle; - commonLoaded = true; + if (!HasLocales) return null; + if (!UsesAssetBundle) return null; + if (bundleAudio == null || currentLoadedLocale != defaultLocale) //TEMPORARY: use the game's default locale until we add localization support + { + if (audioLoaded) return bundleAudio; + // TODO: try/catch for missing assetbundles + currentLoadedLocale = defaultLocale; + bundleAudio = AssetBundle.LoadFromFile(Path.GetFullPath(Path.Combine(Application.streamingAssetsPath, wantAssetBundle, "locale." + defaultLocale))); + audioLoaded = true; + } + return bundleAudio; } - public async UniTask LoadLocalizedAssetBundleAsync() + public AssetBundle GetResourcesAssetBundle() { - if (bundleLocalized != null && !localeLoaded) + if (badBundle) return null; + string path = Path.GetFullPath(Path.Combine(Application.streamingAssetsPath, wantAssetBundle, "common")); + if (bundleResources != null && !resourcesLoaded) { - await bundleLocalized.UnloadAsync(true); - bundleLocalized = null; - localeLoaded = false; - localePreloaded = false; + bundleResources.Unload(true); + bundleResources = null; + resourcesLoaded = false; + resourcesPreloaded = false; + } + if (!File.Exists(path)) + { + badBundle = true; + return null; + } + if (resourcesLoaded) return bundleResources; + if (!UsesAssetBundle) return null; + if (bundleResources == null) + { + bundleResources = AssetBundle.LoadFromFile(path); + resourcesLoaded = true; + } + return bundleResources; + } + + public async UniTask LoadResourcesAssetBundleAsync() + { + if (badBundle) return; + string path = Path.GetFullPath(Path.Combine(Application.streamingAssetsPath, wantAssetBundle, "common")); + if (bundleResources != null && !resourcesLoaded) + { + await bundleResources.UnloadAsync(true); + bundleResources = null; + resourcesLoaded = false; + resourcesPreloaded = false; + } + // ignore all AB checks if path doesn't exist + if (!File.Exists(path)) + { + badBundle = true; + return; + } + if (resourcesPreloaded || resourcesLoaded) return; + resourcesPreloaded = true; + if (!UsesAssetBundle) return; + if (bundleResources != null) return; + AssetBundle bundle = await AssetBundle.LoadFromFileAsync(path).ToUniTask(timing: PlayerLoopTiming.PreLateUpdate); + bundleResources = bundle; + resourcesLoaded = true; + } + + public async UniTask LoadAudioAssetBundleAsync() + { + if (bundleAudio != null && !audioLoaded) + { + await bundleAudio.UnloadAsync(true); + bundleAudio = null; + audioLoaded = false; + audioPreloaded = false; } - if (!hasLocales) return; - if (localePreloaded) return; - localePreloaded = true; - if (!usesAssetBundle) return; - if (localeLoaded && bundleLocalized != null && currentLoadedLocale == defaultLocale) return; + if (!HasLocales) return; + if (audioPreloaded) return; + audioPreloaded = true; + if (!UsesAssetBundle) return; + if (audioLoaded && bundleAudio != null && currentLoadedLocale == defaultLocale) return; - AssetBundle bundle = await AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/locale." + defaultLocale)).ToUniTask(timing: PlayerLoopTiming.PreLateUpdate); - if (localeLoaded && bundleLocalized != null && currentLoadedLocale == defaultLocale) return; + AssetBundle bundle = await AssetBundle.LoadFromFileAsync(Path.GetFullPath(Path.Combine(Application.streamingAssetsPath, wantAssetBundle, "locale." + defaultLocale))).ToUniTask(timing: PlayerLoopTiming.PreLateUpdate); + if (audioLoaded && bundleAudio != null && currentLoadedLocale == defaultLocale) return; - bundleLocalized = bundle; + bundleAudio = bundle; currentLoadedLocale = defaultLocale; - localeLoaded = true; + audioLoaded = true; } public async UniTask LoadGamePrefabAsync() { - if (!usesAssetBundle) return; - if (!commonLoaded) return; - if (bundleCommon == null) return; + if (!UsesAssetBundle) return; + if (!resourcesLoaded) return; + if (bundleResources == null) return; + if (badBundle) return; - AssetBundleRequest request = bundleCommon.LoadAssetAsync(name); + AssetBundleRequest request = bundleResources.LoadAssetAsync(name); request.completed += (op) => OnPrefabLoaded(op as AssetBundleRequest); await request; loadedPrefab = request.asset as GameObject; @@ -576,59 +594,49 @@ namespace HeavenStudio soundSequences = minigame.SoundSequences; } loadedPrefab = prefab; - loadingPrefab = false; } - public GameObject LoadGamePrefab() + public async UniTask PrepareResources() { - if (!usesAssetBundle) return null; + if (!resourcesLoaded) return; + if (bundleResources == null) return; - loadedPrefab = GetCommonAssetBundle().LoadAsset(name); - return loadedPrefab; - } - - public async UniTask LoadCommonAudioClips() - { - if (!commonLoaded) return; - if (bundleCommon == null) return; - - var assets = bundleCommon.LoadAllAssetsAsync(); + var assets = bundleResources.LoadAllAssetsAsync(); await assets; } - public async UniTask LoadLocalizedAudioClips() + public async UniTask PrepareAudio() { - if (!localeLoaded) return; - if (bundleLocalized == null) return; + if (!audioLoaded) return; + if (bundleAudio == null) return; - var assets = bundleLocalized.LoadAllAssetsAsync(); + var assets = bundleAudio.LoadAllAssetsAsync(); await assets; } public async UniTask UnloadAllAssets() { - if (!usesAssetBundle) return; + if (!UsesAssetBundle) return; if (loadedPrefab != null) { loadedPrefab = null; } - if (bundleCommon != null) + if (bundleResources != null) { - await bundleCommon.UnloadAsync(true); - bundleCommon = null; - commonLoaded = false; - commonPreloaded = false; + await bundleResources.UnloadAsync(true); + bundleResources = null; + resourcesLoaded = false; + resourcesPreloaded = false; } - if (bundleLocalized != null) + if (bundleAudio != null) { - await bundleLocalized.UnloadAsync(true); - bundleLocalized = null; - localeLoaded = false; - localePreloaded = false; + await bundleAudio.UnloadAsync(true); + bundleAudio = null; + audioLoaded = false; + audioPreloaded = false; } SoundByte.UnloadAudioClips(name); loadComplete = false; - loadingPrefab = false; } } @@ -1243,8 +1251,8 @@ namespace HeavenStudio string gameName = ((EntityTypes.DropdownObj)e["game"]).CurrentValue; List clips; if (eventCaller.minigames.TryGetValue(gameName, out Minigame game) && game != null) { - IEnumerable audioClips = game.GetCommonAssetBundle().LoadAllAssets(); - var localAssBun = game.GetLocalizedAssetBundle(); + IEnumerable audioClips = game.GetResourcesAssetBundle().LoadAllAssets(); + var localAssBun = game.GetAudioAssetBundle(); if (localAssBun != null) { audioClips = audioClips.Concat(localAssBun.LoadAllAssets()); } diff --git a/Assets/Scripts/UI/Overlays/SkillStarManager.cs b/Assets/Scripts/UI/Overlays/SkillStarManager.cs index ebbc76c0..e3c84ade 100644 --- a/Assets/Scripts/UI/Overlays/SkillStarManager.cs +++ b/Assets/Scripts/UI/Overlays/SkillStarManager.cs @@ -20,7 +20,7 @@ namespace HeavenStudio.Common [SerializeField] private Animator starAnim; [SerializeField] private ParticleSystem starParticle; - public double StarTargetTime { get { return starStart + starLength; } } + public double StarTargetTime { get { return cond.GetUnSwungBeat(starStart + starLength); } } public bool IsEligible { get; private set; } public bool IsCollected { get { return state == StarState.Collected; } } @@ -41,14 +41,14 @@ namespace HeavenStudio.Common { if (cond.songPositionInBeatsAsDouble > starStart && state == StarState.In) { - double offset = cond.SecsToBeats(Minigame.AceEarlyTime()-1, cond.GetBpmAtBeat(StarTargetTime)); - if (cond.songPositionInBeatsAsDouble <= starStart + starLength + offset) + double offset = cond.SecsToBeats(Minigame.AceEarlyTime() - 1, cond.GetBpmAtBeat(StarTargetTime)); + if (cond.unswungSongPositionInBeatsAsDouble <= StarTargetTime + offset) starAnim.DoScaledAnimation("StarIn", starStart, starLength + (float)offset); else starAnim.Play("StarIn", -1, 1f); - - offset = cond.SecsToBeats(Minigame.AceLateTime()-1, cond.GetBpmAtBeat(StarTargetTime)); - if (cond.songPositionInBeatsAsDouble > starStart + starLength + offset) + + offset = cond.SecsToBeats(Minigame.AceLateTime() - 1, cond.GetBpmAtBeat(StarTargetTime)); + if (cond.unswungSongPositionInBeatsAsDouble > StarTargetTime + offset) KillStar(); } } @@ -87,15 +87,15 @@ namespace HeavenStudio.Common starLength = length; TimingAccuracyDisplay.instance.StartStarFlash(); - + starAnim.DoScaledAnimation("StarIn", beat, length); } public bool DoStarJust() { - if (state == StarState.In && - cond.songPositionInBeatsAsDouble >= StarTargetTime + cond.SecsToBeats(Minigame.AceEarlyTime()-1, cond.GetBpmAtBeat(StarTargetTime)) && - cond.songPositionInBeatsAsDouble <= StarTargetTime + cond.SecsToBeats(Minigame.AceLateTime()-1, cond.GetBpmAtBeat(StarTargetTime)) + if (state == StarState.In && + cond.unswungSongPositionInBeatsAsDouble >= StarTargetTime + cond.SecsToBeats(Minigame.AceEarlyTime() - 1, cond.GetBpmAtBeat(StarTargetTime)) && + cond.unswungSongPositionInBeatsAsDouble <= StarTargetTime + cond.SecsToBeats(Minigame.AceLateTime() - 1, cond.GetBpmAtBeat(StarTargetTime)) ) { state = StarState.Collected; @@ -111,7 +111,7 @@ namespace HeavenStudio.Common public void KillStar() { - if (state == StarState.In && cond.songPositionInBeatsAsDouble >= starStart + starLength*0.5f || !cond.isPlaying) + if (state == StarState.In && cond.songPositionInBeatsAsDouble >= starStart + (starLength * 0.5f) || !cond.isPlaying) { IsEligible = false; state = StarState.Out; diff --git a/Assets/Scripts/Util/SoundByte.cs b/Assets/Scripts/Util/SoundByte.cs index f6f0e54b..22260fa8 100644 --- a/Assets/Scripts/Util/SoundByte.cs +++ b/Assets/Scripts/Util/SoundByte.cs @@ -81,9 +81,9 @@ namespace HeavenStudio.Util public static void PreloadGameAudioClips(Minigames.Minigame inf) { - if (inf.usesAssetBundle) + if (inf.UsesAssetBundle) { - var cmnAb = inf.GetCommonAssetBundle(); + var cmnAb = inf.GetResourcesAssetBundle(); if (cmnAb != null) { cmnAb.LoadAllAssetsAsync().completed += (op) => @@ -94,7 +94,7 @@ namespace HeavenStudio.Util } }; } - var locAb = inf.GetLocalizedAssetBundle(); + var locAb = inf.GetAudioAssetBundle(); if (locAb != null) { locAb.LoadAllAssetsAsync().completed += (op) => @@ -131,9 +131,9 @@ namespace HeavenStudio.Util name = $"games/{name}"; } if (audioClips.ContainsKey(name)) return; - if (inf.usesAssetBundle) + if (inf.UsesAssetBundle) { - var cmnAb = inf.GetCommonAssetBundle(); + var cmnAb = inf.GetResourcesAssetBundle(); if (cmnAb != null && cmnAb.Contains(name)) { var request = cmnAb.LoadAssetAsync(name); @@ -144,7 +144,7 @@ namespace HeavenStudio.Util } else { - var locAb = inf.GetLocalizedAssetBundle(); + var locAb = inf.GetAudioAssetBundle(); if (locAb != null && locAb.Contains(name)) { var request = locAb.LoadAssetAsync(name); @@ -232,12 +232,12 @@ namespace HeavenStudio.Util var inf = GameManager.instance.GetGameInfo(game); //first try the game's common assetbundle // Debug.Log("Jukebox loading sound " + soundName + " from common"); - clip = inf.GetCommonAssetBundle()?.LoadAsset(soundName); + clip = inf.GetResourcesAssetBundle()?.LoadAsset(soundName); //then the localized one if (clip == null) { // Debug.Log("Jukebox loading sound " + soundName + " from locale"); - clip = inf.GetLocalizedAssetBundle()?.LoadAsset(soundName); + clip = inf.GetAudioAssetBundle()?.LoadAsset(soundName); } } } @@ -274,7 +274,7 @@ namespace HeavenStudio.Util var inf = GameManager.instance.GetGameInfo(gameName); if (inf != null) { - return GetClipLength($"games/{name}", pitch, inf.usesAssetBundle ? gameName : null); + return GetClipLength($"games/{name}", pitch, inf.UsesAssetBundle ? gameName : null); } return double.NaN; @@ -301,12 +301,12 @@ namespace HeavenStudio.Util var inf = GameManager.instance.GetGameInfo(game); //first try the game's common assetbundle // Debug.Log("Jukebox loading sound " + soundName + " from common"); - clip = inf.GetCommonAssetBundle()?.LoadAsset(soundName); + clip = inf.GetResourcesAssetBundle()?.LoadAsset(soundName); //then the localized one if (clip == null) { // Debug.Log("Jukebox loading sound " + soundName + " from locale"); - clip = inf.GetLocalizedAssetBundle()?.LoadAsset(soundName); + clip = inf.GetAudioAssetBundle()?.LoadAsset(soundName); } } } @@ -374,12 +374,12 @@ namespace HeavenStudio.Util var inf = GameManager.instance.GetGameInfo(game); //first try the game's common assetbundle // Debug.Log("Jukebox loading sound " + soundName + " from common"); - clip = inf.GetCommonAssetBundle()?.LoadAsset(soundName); + clip = inf.GetResourcesAssetBundle()?.LoadAsset(soundName); //then the localized one if (clip == null) { // Debug.Log("Jukebox loading sound " + soundName + " from locale"); - clip = inf.GetLocalizedAssetBundle()?.LoadAsset(soundName); + clip = inf.GetAudioAssetBundle()?.LoadAsset(soundName); } } } @@ -424,7 +424,7 @@ namespace HeavenStudio.Util var inf = GameManager.instance.GetGameInfo(gameName); if (GameManager.instance.currentGame == gameName || forcePlay) { - return PlayOneShot($"games/{name}", beat, pitch, volume, looping, inf.usesAssetBundle ? gameName : null, offset, ignoreConductorPause); + return PlayOneShot($"games/{name}", beat, pitch, volume, looping, inf.UsesAssetBundle ? gameName : null, offset, ignoreConductorPause); } return null; @@ -440,7 +440,7 @@ namespace HeavenStudio.Util var inf = GameManager.instance.GetGameInfo(gameName); if (GameManager.instance.currentGame == gameName || forcePlay) { - return PlayOneShotScheduled($"games/{name}", targetTime, pitch, volume, looping, inf.usesAssetBundle ? gameName : null, ignoreConductorPause); + return PlayOneShotScheduled($"games/{name}", targetTime, pitch, volume, looping, inf.UsesAssetBundle ? gameName : null, ignoreConductorPause); } return null;