fix certain types of sounds firing a frame late

This commit is contained in:
minenice55 2024-01-24 00:17:35 -05:00
parent 23d9edf5fe
commit b94a70fbc6
5 changed files with 74 additions and 52 deletions

View file

@ -189,6 +189,7 @@ namespace HeavenStudio
RiqBeatmap chart = GameManager.instance.Beatmap; RiqBeatmap chart = GameManager.instance.Beatmap;
double offset = chart.data.offset; double offset = chart.data.offset;
double dspTime = AudioSettings.dspTime; double dspTime = AudioSettings.dspTime;
dspStart = dspTime;
startPos = GetSongPosFromBeat(beat); startPos = GetSongPosFromBeat(beat);
firstBeatOffset = offset; firstBeatOffset = offset;
@ -213,10 +214,6 @@ namespace HeavenStudio
musicSource.pitch = timelinePitch; musicSource.pitch = timelinePitch;
Debug.Log($"playback scheduled for dsptime {dspStart}"); Debug.Log($"playback scheduled for dsptime {dspStart}");
} }
if (musicSource.clip == null)
{
dspStart = dspTime;
}
songPosBeat = beat; songPosBeat = beat;
startBeat = songPosBeat; startBeat = songPosBeat;
@ -404,7 +401,7 @@ namespace HeavenStudio
} }
} }
double MapTimeToPitchChanges(double time) public double MapTimeToPitchChanges(double time)
{ {
double counter = 0; double counter = 0;
double lastChangeTime = 0; double lastChangeTime = 0;

View file

@ -21,7 +21,7 @@ namespace HeavenStudio
[Header("Lists")] [Header("Lists")]
[NonSerialized] public RiqBeatmap Beatmap = new(); [NonSerialized] public RiqBeatmap Beatmap = new();
private List<GameObject> preloadedGames = new(); private Dictionary<string, GameObject> cachedGamePrefabs = new();
[NonSerialized] public ObjectPool<Sound> SoundObjects; [NonSerialized] public ObjectPool<Sound> SoundObjects;
[Header("Components")] [Header("Components")]
@ -1092,9 +1092,11 @@ namespace HeavenStudio
{ {
ResetCamera(); // resetting camera before setting new minigame so minigames can set camera values in their awake call - Rasmus ResetCamera(); // resetting camera before setting new minigame so minigames can set camera values in their awake call - Rasmus
Destroy(currentGameO); GameObject prefab = GetGame(game);
if (prefab == null) return;
currentGameO = Instantiate(GetGame(game)); Destroy(currentGameO);
currentGameO = Instantiate(prefab);
if (currentGameO.TryGetComponent<Minigame>(out var minigame)) if (currentGameO.TryGetComponent<Minigame>(out var minigame))
{ {
_currentMinigame = minigame; _currentMinigame = minigame;
@ -1112,6 +1114,7 @@ namespace HeavenStudio
public void DestroyGame() public void DestroyGame()
{ {
cachedGamePrefabs.Clear();
SetGame("noGame"); SetGame("noGame");
} }
@ -1152,29 +1155,40 @@ namespace HeavenStudio
.Select(x => GetGameInfo(x)) .Select(x => GetGameInfo(x))
.Where(x => x != null) .Where(x => x != null)
.Where(x => !x.fxOnly) .Where(x => !x.fxOnly)
.Select(x => x.LoadableName); .Where(x => x.LoadableName is not "noGame" or "" or null);
name = gameInfos.FirstOrDefault() ?? "noGame"; if (gameInfos.Count() > 0)
}
else
{
if (gameInfo.usesAssetBundle)
{ {
//game is packed in an assetbundle, load from that instead gameInfo = gameInfos.FirstOrDefault();
if (gameInfo.AssetsLoaded && gameInfo.LoadedPrefab != null) return gameInfo.LoadedPrefab; if (gameInfo == null) return Resources.Load<GameObject>($"Games/noGame");
}
try else
{ {
return gameInfo.GetCommonAssetBundle().LoadAsset<GameObject>(name); return Resources.Load<GameObject>($"Games/noGame");
}
catch (Exception e)
{
Debug.LogWarning($"Failed to load assetbundle for game {name}, using sync loading: {e.Message}");
return Resources.Load<GameObject>($"Games/{name}");
}
} }
} }
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}");
return Resources.Load<GameObject>($"Games/{name}");
}
}
return Resources.Load<GameObject>($"Games/{name}");
}
else
{
Debug.LogWarning($"Game {name} not found, using noGame");
return Resources.Load<GameObject>($"Games/noGame");
} }
return Resources.Load<GameObject>($"Games/{name}");
} }
public Minigames.Minigame GetGameInfo(string name) public Minigames.Minigame GetGameInfo(string name)

View file

@ -479,9 +479,7 @@ namespace HeavenStudio
{ {
if (AssetsLoaded || !usesAssetBundle) return; if (AssetsLoaded || !usesAssetBundle) return;
await UniTask.WhenAll(LoadCommonAssetBundleAsync(), LoadLocalizedAssetBundleAsync()); await UniTask.WhenAll(LoadCommonAssetBundleAsync(), LoadLocalizedAssetBundleAsync());
await UniTask.WhenAll(LoadGamePrefabAsync()); await UniTask.WhenAll(LoadGamePrefabAsync(), LoadCommonAudioClips(), LoadLocalizedAudioClips());
await UniTask.WhenAll(LoadCommonAudioClips());
await UniTask.WhenAll(LoadLocalizedAudioClips());
} }
public async UniTask LoadCommonAssetBundleAsync() public async UniTask LoadCommonAssetBundleAsync()
@ -547,6 +545,14 @@ namespace HeavenStudio
} }
} }
public GameObject LoadGamePrefab()
{
if (!usesAssetBundle) return null;
loadedPrefab = GetCommonAssetBundle().LoadAsset<GameObject>(name);
return loadedPrefab;
}
public async UniTask LoadCommonAudioClips() public async UniTask LoadCommonAudioClips()
{ {
if (!commonLoaded) return; if (!commonLoaded) return;
@ -556,14 +562,6 @@ namespace HeavenStudio
var assets = bundleCommon.LoadAllAssetsAsync(); var assets = bundleCommon.LoadAllAssetsAsync();
await assets; await assets;
// await UniTask.SwitchToThreadPool();
// foreach (var asset in assets.allAssets)
// {
// AudioClip clip = asset as AudioClip;
// commonAudioClips.Add(clip.name, clip);
// }
// await UniTask.SwitchToMainThread();
} }
public async UniTask LoadLocalizedAudioClips() public async UniTask LoadLocalizedAudioClips()
@ -575,14 +573,6 @@ namespace HeavenStudio
var assets = bundleLocalized.LoadAllAssetsAsync(); var assets = bundleLocalized.LoadAllAssetsAsync();
await assets; await assets;
// await UniTask.SwitchToThreadPool();
// foreach (var asset in assets.allAssets)
// {
// AudioClip clip = asset as AudioClip;
// localeAudioClips.Add(clip.name, clip);
// }
// await UniTask.SwitchToMainThread();
} }
public async UniTask UnloadAllAssets() public async UniTask UnloadAllAssets()

View file

@ -70,6 +70,7 @@ namespace HeavenStudio.Util
audioSource = GetComponent<AudioSource>(); audioSource = GetComponent<AudioSource>();
cond = Conductor.instance; cond = Conductor.instance;
double dspTime = AudioSettings.dspTime;
available = false; available = false;
audioSource.clip = clip; audioSource.clip = clip;
@ -85,8 +86,8 @@ namespace HeavenStudio.Util
{ {
playInstant = true; playInstant = true;
played = true; played = true;
startTime = AudioSettings.dspTime; startTime = dspTime;
audioSource.PlayScheduled(startTime); audioSource.Play();
} }
else else
{ {
@ -94,15 +95,17 @@ namespace HeavenStudio.Util
if (cond != null) if (cond != null)
{ {
scheduledPitch = cond.SongPitch; scheduledPitch = cond.SongPitch;
startTime = (AudioSettings.dspTime + (cond.GetSongPosFromBeat(beat) - cond.songPositionAsDouble) / (double)scheduledPitch) - offset; startTime = (dspTime + (cond.GetSongPosFromBeat(beat) - cond.songPositionAsDouble) / (double)scheduledPitch) - offset;
} }
if (scheduledPitch != 0 && AudioSettings.dspTime >= startTime) if (scheduledPitch != 0 && dspTime >= startTime)
{ {
audioSource.PlayScheduled(startTime); audioSource.PlayScheduled(startTime);
played = true;
queued = true; queued = true;
} }
} }
Update();
} }
private void Update() private void Update()
@ -157,7 +160,7 @@ namespace HeavenStudio.Util
audioSource.UnPause(); audioSource.UnPause();
} }
scheduledPitch = cond.SongPitch; scheduledPitch = cond.SongPitch;
startTime = (dspTime + (cond.GetSongPosFromBeat(beat) - cond.songPositionAsDouble) / (double)scheduledPitch); startTime = (dspTime + (cond.GetSongPosFromBeat(beat) - cond.songPositionAsDouble) / (double)scheduledPitch) - offset;
if (queued) if (queued)
audioSource.SetScheduledStartTime(startTime); audioSource.SetScheduledStartTime(startTime);
} }
@ -203,7 +206,7 @@ namespace HeavenStudio.Util
{ {
if (looping && loopEndBeat != -1) // Looping sounds play forever unless params are set. if (looping && loopEndBeat != -1) // Looping sounds play forever unless params are set.
{ {
if (cond.songPositionInBeatsAsDouble > loopEndBeat) if (cond.songPositionInBeatsAsDouble >= loopEndBeat)
{ {
KillLoop(fadeTime); KillLoop(fadeTime);
loopDone = true; loopDone = true;
@ -257,12 +260,22 @@ namespace HeavenStudio.Util
{ {
if (!gameObject.activeSelf) return; if (!gameObject.activeSelf) return;
this.bendedPitch = bendedPitch; this.bendedPitch = bendedPitch;
if (bendTime == 0)
{
audioSource.pitch = bendedPitch;
return;
}
StartCoroutine(BendUpLoop(bendTime)); StartCoroutine(BendUpLoop(bendTime));
} }
public void BendDown(float bendTime) public void BendDown(float bendTime)
{ {
if (!gameObject.activeSelf) return; if (!gameObject.activeSelf) return;
if (bendTime == 0)
{
audioSource.pitch = pitch;
return;
}
StartCoroutine(BendDownLoop(bendTime)); StartCoroutine(BendDownLoop(bendTime));
} }
@ -301,6 +314,11 @@ namespace HeavenStudio.Util
public void KillLoop(double fadeTime) public void KillLoop(double fadeTime)
{ {
if (!gameObject.activeSelf) return; if (!gameObject.activeSelf) return;
if (fadeTime == 0)
{
GameManager.instance.SoundObjects.Release(this);
return;
}
StartCoroutine(FadeLoop(fadeTime)); StartCoroutine(FadeLoop(fadeTime));
} }

View file

@ -48,5 +48,8 @@ MonoBehaviour:
- Assets/Scripts/LevelEditor/Timeline/SpecialTmeline/SectionDialog.cs - Assets/Scripts/LevelEditor/Timeline/SpecialTmeline/SectionDialog.cs
- Assets/Scripts/LevelEditor/Timeline/SpecialTmeline/TimelineObjs/SectionTimelineObj.cs - Assets/Scripts/LevelEditor/Timeline/SpecialTmeline/TimelineObjs/SectionTimelineObj.cs
- Assets/Scripts/Games/DJSchool/Student.cs - Assets/Scripts/Games/DJSchool/Student.cs
- Assets/Scripts/UI/PauseMenu.cs
- Assets/Scripts/Util/Sound.cs
- Assets/Scripts/Conductor.cs
PathsToSkipImportEvent: [] PathsToSkipImportEvent: []
PathsToIgnoreOverwriteSettingOnAttribute: [] PathsToIgnoreOverwriteSettingOnAttribute: []