fix game asset loading for real (#861)

fix copy paste not using timeline marker's time
correct more uses of swung / unswung beat
This commit is contained in:
minenice55 2024-04-10 01:05:47 -04:00 committed by minenice55
parent 9f8f5b25a2
commit 09f0fb8151
8 changed files with 243 additions and 229 deletions

View File

@ -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;
}

View File

@ -167,7 +167,9 @@ namespace HeavenStudio
SeekMusicToTime(startPos, offset);
songPos = startPos;
songPosBeat = GetBeatFromSongPos(time);
songPositionInBeatsAsDouble = GetSwungBeat(songPosBeat);
gameManager.SetCurrentEventToClosest(beat, true);
}

View File

@ -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,18 +1016,13 @@ 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);
}
List<RiqEntity> allEnds = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "end" });
if (allEnds.Count > 0)
@ -1099,6 +1090,13 @@ namespace HeavenStudio
#endregion
/// <summary>
/// While playing a chart, switches the currently active game
/// Should only be called by chart entities
/// </summary>
/// <param name="game">name of the game to switch to</param>
/// <param name="beat">beat of the chart entity calling the switch</param>
/// <param name="flash">hide the screen during the switch</param>
public void SwitchGame(string game, double beat, bool flash)
{
if (game != currentGame)
@ -1142,11 +1140,16 @@ namespace HeavenStudio
SetAmbientGlowToCurrentMinigameColor();
}
/// <summary>
/// Immediately sets the current minigame to the specified game
/// </summary>
/// <param name="game"></param>
/// <param name="useMinigameColor"></param>
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;
/// <summary>
/// Waits for a given game to preload, then sets it as the current game
/// </summary>
/// <param name="game"></param>
/// <param name="useMinigameColor"></param>
/// <returns></returns>
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<Minigame>().SoundSequences;
SoundByte.UnloadAudioClips();
SetGame("noGame");
}
public GameObject GetGame(string name)
/// <summary>
/// Get the game prefab for a given game name
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public GameObject GetGamePrefab(string name)
{
if (name is null or "" or "noGame")
{
@ -1242,19 +1247,12 @@ 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
{
Debug.LogWarning($"Game prefab wasn't cached, loading from assetbundle for game {name}");
return gameInfo.LoadGamePrefab();
}
catch (Exception e)
{
Debug.LogWarning($"Failed to load assetbundle for game {name}, using sync loading: {e.Message}");
// 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<GameObject>($"Games/{name}");
if (prefab != null)
{
@ -1266,7 +1264,6 @@ namespace HeavenStudio
return Resources.Load<GameObject>($"Games/noGame");
}
}
}
// games with no assetbundle (usually indev games)
prefab = Resources.Load<GameObject>($"Games/{name}");
if (prefab != null)
@ -1293,10 +1290,13 @@ namespace HeavenStudio
public bool TryGetMinigame<T>(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;
}

View File

@ -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);

View File

@ -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; }
@ -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<RectTransform>();
var rot = 0.0f;
if (Conductor.instance.metronome)
RectTransform rectTransform = MetronomeBTN.transform.GetChild(1).GetComponent<RectTransform>();
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<string, dynamic>(newEntity.dynamicData)) {
if (value is EntityTypes.DropdownObj dd) {
foreach ((var key, var value) in new Dictionary<string, dynamic>(newEntity.dynamicData))
{
if (value is EntityTypes.DropdownObj dd)
{
newEntity[key] = new EntityTypes.DropdownObj(dd.value, dd.Values);
}
}

View File

@ -384,26 +384,26 @@ namespace HeavenStudio
public List<string> 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;
}
public async UniTask LoadLocalizedAssetBundleAsync()
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 (bundleLocalized != null && !localeLoaded)
{
await bundleLocalized.UnloadAsync(true);
bundleLocalized = null;
localeLoaded = false;
localePreloaded = false;
}
if (!hasLocales) return;
if (localePreloaded) return;
localePreloaded = true;
if (!usesAssetBundle) return;
if (localeLoaded && bundleLocalized != 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;
bundleLocalized = bundle;
if (audioLoaded) return bundleAudio;
// TODO: try/catch for missing assetbundles
currentLoadedLocale = defaultLocale;
localeLoaded = true;
bundleAudio = AssetBundle.LoadFromFile(Path.GetFullPath(Path.Combine(Application.streamingAssetsPath, wantAssetBundle, "locale." + defaultLocale)));
audioLoaded = true;
}
return bundleAudio;
}
public AssetBundle GetResourcesAssetBundle()
{
if (badBundle) return null;
string path = Path.GetFullPath(Path.Combine(Application.streamingAssetsPath, wantAssetBundle, "common"));
if (bundleResources != null && !resourcesLoaded)
{
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 (audioPreloaded) return;
audioPreloaded = true;
if (!UsesAssetBundle) return;
if (audioLoaded && bundleAudio != 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;
bundleAudio = bundle;
currentLoadedLocale = defaultLocale;
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<GameObject>(name);
AssetBundleRequest request = bundleResources.LoadAssetAsync<GameObject>(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<GameObject>(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<string> clips;
if (eventCaller.minigames.TryGetValue(gameName, out Minigame game) && game != null) {
IEnumerable<AudioClip> audioClips = game.GetCommonAssetBundle().LoadAllAssets<AudioClip>();
var localAssBun = game.GetLocalizedAssetBundle();
IEnumerable<AudioClip> audioClips = game.GetResourcesAssetBundle().LoadAllAssets<AudioClip>();
var localAssBun = game.GetAudioAssetBundle();
if (localAssBun != null) {
audioClips = audioClips.Concat(localAssBun.LoadAllAssets<AudioClip>());
}

View File

@ -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; } }
@ -42,13 +42,13 @@ 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)
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)
if (cond.unswungSongPositionInBeatsAsDouble > StarTargetTime + offset)
KillStar();
}
}
@ -94,8 +94,8 @@ namespace HeavenStudio.Common
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))
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;

View File

@ -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<AudioClip>().completed += (op) =>
@ -94,7 +94,7 @@ namespace HeavenStudio.Util
}
};
}
var locAb = inf.GetLocalizedAssetBundle();
var locAb = inf.GetAudioAssetBundle();
if (locAb != null)
{
locAb.LoadAllAssetsAsync<AudioClip>().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<AudioClip>(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<AudioClip>(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<AudioClip>(soundName);
clip = inf.GetResourcesAssetBundle()?.LoadAsset<AudioClip>(soundName);
//then the localized one
if (clip == null)
{
// Debug.Log("Jukebox loading sound " + soundName + " from locale");
clip = inf.GetLocalizedAssetBundle()?.LoadAsset<AudioClip>(soundName);
clip = inf.GetAudioAssetBundle()?.LoadAsset<AudioClip>(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<AudioClip>(soundName);
clip = inf.GetResourcesAssetBundle()?.LoadAsset<AudioClip>(soundName);
//then the localized one
if (clip == null)
{
// Debug.Log("Jukebox loading sound " + soundName + " from locale");
clip = inf.GetLocalizedAssetBundle()?.LoadAsset<AudioClip>(soundName);
clip = inf.GetAudioAssetBundle()?.LoadAsset<AudioClip>(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<AudioClip>(soundName);
clip = inf.GetResourcesAssetBundle()?.LoadAsset<AudioClip>(soundName);
//then the localized one
if (clip == null)
{
// Debug.Log("Jukebox loading sound " + soundName + " from locale");
clip = inf.GetLocalizedAssetBundle()?.LoadAsset<AudioClip>(soundName);
clip = inf.GetAudioAssetBundle()?.LoadAsset<AudioClip>(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;