fix major issue with pooled sound objects

rebalance ranking audio
fix issues with some effects in play mode
This commit is contained in:
minenice55 2023-11-25 23:03:23 -05:00
parent 79ec1449b8
commit 6f923f4754
31 changed files with 265 additions and 91 deletions

Binary file not shown.

View file

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: d98376004e499164ba964a236415b6b1
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:

Binary file not shown.

View file

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 119a69280a5739147bc49b8e10386e2a
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:

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 38aa84c219986a94cb70204f29e86c47
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:

Binary file not shown.

View file

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 91e122c94e9c3cf419daa70428cb69e5
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:

Binary file not shown.

View file

@ -0,0 +1,22 @@
fileFormatVersion: 2
guid: 3301b29ac7b6f394a8747997bf949724
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:

View file

@ -206,6 +206,22 @@ PrefabInstance:
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3954997730746798104, guid: 75ce9c0b59ff27f46a011e0cafc17fb3, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3954997730746798104, guid: 75ce9c0b59ff27f46a011e0cafc17fb3, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3954997730746798104, guid: 75ce9c0b59ff27f46a011e0cafc17fb3, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3954997730746798104, guid: 75ce9c0b59ff27f46a011e0cafc17fb3, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5046962229971873052, guid: 75ce9c0b59ff27f46a011e0cafc17fb3, type: 3}
propertyPath: m_AnchorMax.y
value: 0
@ -426,6 +442,50 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &645596968
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 645596970}
- component: {fileID: 645596969}
m_Layer: 0
m_Name: StretchCameraVFX
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &645596969
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 645596968}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c41d0b7047b9b1d4e91d4cf101fa025b, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &645596970
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 645596968}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1157422643
GameObject:
m_ObjectHideFlags: 0

View file

@ -50,7 +50,8 @@ namespace HeavenStudio
private Minigame _currentMinigame;
[NonSerialized] public bool autoplay;
[NonSerialized] public bool canInput = true;
[NonSerialized] public RiqEntity currentSection, nextSection;
[NonSerialized] public RiqEntity lastSection, currentSection;
[NonSerialized] public double nextSectionBeat;
public double SectionProgress { get; private set; }
public bool GameHasSplitColours
@ -70,7 +71,7 @@ namespace HeavenStudio
List<RiqEntity> allGameSwitches;
public event Action<double> onBeatChanged;
public event Action<RiqEntity> onSectionChange;
public event Action<RiqEntity, RiqEntity> onSectionChange;
public event Action<double> onBeatPulse;
public int BeatmapEntities()
@ -331,7 +332,7 @@ namespace HeavenStudio
public void ScoreInputAccuracy(double beat, double accuracy, bool late, double time, float weight = 1, bool doDisplay = true, int category = 0)
{
totalInputs += weight;
totalPlayerAccuracy += accuracy * weight;
totalPlayerAccuracy += Math.Pow(accuracy, weight);
judgementInfo.inputs.Add(new JudgementManager.InputInfo
{
@ -358,6 +359,15 @@ namespace HeavenStudio
TimingAccuracyDisplay.instance.MakeAccuracyVfx(time, late);
}
public void DoSectionCompletion(double beat, bool clear, string name, double score)
{
judgementInfo.medals.Add(new JudgementManager.MedalInfo
{
beat = beat,
cleared = clear
});
}
static bool StringStartsWith(string a, string b)
{
int aLen = a.Length;
@ -495,13 +505,17 @@ namespace HeavenStudio
if (cond.songPositionInBeatsAsDouble >= sectionBeats[currentSectionEvent])
{
Debug.Log("Section " + Beatmap.SectionMarkers[currentSectionEvent]["sectionName"] + " started");
currentSection = Beatmap.SectionMarkers[currentSectionEvent];
lastSection = currentSection;
if (currentSectionEvent < Beatmap.SectionMarkers.Count)
currentSection = Beatmap.SectionMarkers[currentSectionEvent];
else
currentSection = null;
currentSectionEvent++;
if (currentSectionEvent < Beatmap.SectionMarkers.Count)
nextSection = Beatmap.SectionMarkers[currentSectionEvent];
nextSectionBeat = Beatmap.SectionMarkers[currentSectionEvent].beat;
else
nextSection = default(RiqEntity);
onSectionChange?.Invoke(currentSection);
nextSectionBeat = endBeat;
onSectionChange?.Invoke(currentSection, lastSection);
}
}
@ -580,10 +594,7 @@ namespace HeavenStudio
{
double currectSectionStart = cond.GetSongPosFromBeat(currentSection.beat);
if (nextSection == null)
SectionProgress = (cond.songPosition - currectSectionStart) / (cond.GetSongPosFromBeat(endBeat) - currectSectionStart);
else
SectionProgress = (cond.songPosition - currectSectionStart) / (cond.GetSongPosFromBeat(nextSection.beat) - currectSectionStart);
SectionProgress = (cond.songPosition - currectSectionStart) / (cond.GetSongPosFromBeat(nextSectionBeat) - currectSectionStart);
}
}
@ -676,31 +687,18 @@ namespace HeavenStudio
public void Stop(double beat, bool restart = false, float restartDelay = 0f)
{
// I feel like I should standardize the names
SkillStarManager.instance.KillStar();
TimingAccuracyDisplay.instance.StopStarFlash();
GoForAPerfect.instance.Disable();
SectionMedalsManager.instance.OnRemixEnd(endBeat, currentSection);
Minigame miniGame = currentGameO.GetComponent<Minigame>();
if (miniGame != null)
miniGame.OnStop(beat);
Conductor.instance.Stop(beat);
SetCurrentEventToClosest(beat);
//onBeatChanged?.Invoke(beat);
// I feel like I should standardize the names
SkillStarManager.instance.KillStar();
TimingAccuracyDisplay.instance.StopStarFlash();
GoForAPerfect.instance.Disable();
SectionMedalsManager.instance.OnRemixEnd();
// pass this data to rating screen + stats
// Debug.Log($"== Playthrough statistics of {Beatmap["remixtitle"]} (played at {System.DateTime.Now:yyyy-MM-dd HH:mm:ss}) ==");
// Debug.Log($"Average input offset for playthrough: {averageInputOffset}ms");
// Debug.Log($"Accuracy for playthrough: {(PlayerAccuracy * 100): 0.00}");
// Debug.Log($"Cleared {clearedSections.FindAll(c => c).Count} sections out of {Beatmap.SectionMarkers.Count}");
// if (SkillStarManager.instance.IsCollected)
// Debug.Log($"Skill Star collected");
// else
// Debug.Log($"Skill Star not collected");
// if (GoForAPerfect.instance.perfect)
// Debug.Log($"Perfect Clear!");
KillAllSounds();
if (restart)
@ -721,7 +719,12 @@ namespace HeavenStudio
Application.backgroundLoadingPriority = ThreadPriority.Normal;
}
private IEnumerator WaitReadyAndPlayCo(double beat)
public void SafePlay(double beat, float delay, bool discord)
{
StartCoroutine(WaitReadyAndPlayCo(beat, delay, discord));
}
private IEnumerator WaitReadyAndPlayCo(double beat, float delay = 1f, bool discord = true)
{
WaitUntil yieldOverlays = new WaitUntil(() => OverlaysManager.OverlaysReady);
WaitUntil yieldBeatmap = new WaitUntil(() => Beatmap != null && Beatmap.Entities.Count > 0);
@ -729,7 +732,7 @@ namespace HeavenStudio
// wait for overlays to be ready
yield return yieldOverlays;
// wait for first game to be loaded
// wait for beatmap to be loaded
yield return yieldBeatmap;
//wait for audio clip to be loaded
yield return yieldAudio;
@ -737,11 +740,14 @@ namespace HeavenStudio
SkillStarManager.instance.KillStar();
TimingAccuracyDisplay.instance.StopStarFlash();
GoForAPerfect.instance.Disable();
SectionMedalsManager.instance?.OnRemixEnd();
SectionMedalsManager.instance?.Reset();
GlobalGameManager.UpdateDiscordStatus(Beatmap["remixtitle"].ToString(), false, true);
if (discord)
{
GlobalGameManager.UpdateDiscordStatus(Beatmap["remixtitle"].ToString(), false, true);
}
Play(beat, 1f);
Play(beat, delay);
yield break;
}
@ -924,8 +930,8 @@ namespace HeavenStudio
}
}
currentSection = default(RiqEntity);
nextSection = default(RiqEntity);
lastSection = null;
currentSection = null;
if (Beatmap.SectionMarkers.Count > 0)
{
currentSectionEvent = 0;
@ -939,7 +945,7 @@ namespace HeavenStudio
currentSectionEvent = t;
}
}
onSectionChange?.Invoke(currentSection);
onSectionChange?.Invoke(currentSection, lastSection);
SeekAheadAndPreload(beat);
}

View file

@ -433,10 +433,10 @@ namespace HeavenStudio.Games
return null;
}
public void ScoreMiss(float weight = 1f)
public void ScoreMiss(float weight = 1f, int category = 0)
{
double beat = Conductor.instance?.songPositionInBeatsAsDouble ?? -1;
GameManager.instance.ScoreInputAccuracy(beat, 0, true, NgLateTime(), weight, false);
GameManager.instance.ScoreInputAccuracy(beat, 0, true, NgLateTime(), weight, false, category);
if (weight > 0)
{
GoForAPerfect.instance.Miss();

View file

@ -26,6 +26,8 @@ namespace HeavenStudio.Games
public double startBeat;
public double timer;
public int category;
public float weight = 1f;
public bool isEligible = true;
public bool canHit = true; //Indicates if you can still hit the cue or not. If set to false, it'll guarantee a miss
@ -269,7 +271,7 @@ namespace HeavenStudio.Games
if (countsForAccuracy && !(noAutoplay || autoplayOnly) && isEligible)
{
GameManager.instance.ScoreInputAccuracy(startBeat + timer, TimeToAccuracy(time), time > 1.0, time);
GameManager.instance.ScoreInputAccuracy(startBeat + timer, TimeToAccuracy(time), time > 1.0, time, weight, true, category);
if (state >= 1f || state <= -1f)
{
GoForAPerfect.instance.Miss();
@ -343,7 +345,7 @@ namespace HeavenStudio.Games
if (countsForAccuracy && !(noAutoplay || autoplayOnly))
{
GameManager.instance.ScoreInputAccuracy(startBeat + timer, 0, true, 2.0, 1, false);
GameManager.instance.ScoreInputAccuracy(startBeat + timer, 0, true, 2.0, weight, false, category);
GoForAPerfect.instance.Miss();
SectionMedalsManager.instance.MakeIneligible();
}

View file

@ -233,6 +233,19 @@ namespace HeavenStudio
float h = Screen.height / 1080f;
scaler.scaleFactor = Mathf.Min(w, h);
InputController currentController = PlayerInput.GetInputController(1);
if (currentController.GetLastButtonDown() > 0)
{
if (didRank)
{
// start the sequence for epilogue
GlobalGameManager.LoadScene("Title", 0.35f, 0.5f);
}
else if (barStarted)
{
barTime = Time.time - barStartTime;
}
}
if (barStarted)
{
float t = Time.time - barStartTime;
@ -286,14 +299,6 @@ namespace HeavenStudio
}
}
if (didRank)
{
InputController currentController = PlayerInput.GetInputController(1);
if (currentController.GetLastButtonDown() > 0)
{
GlobalGameManager.LoadScene("Title", 0.35f, 0.5f);
}
}
}
}
}

View file

@ -696,7 +696,7 @@ namespace HeavenStudio.Editor.Track
TimelineSongPosLine.gameObject.SetActive(true);
}
GameManager.instance.Play(time);
GameManager.instance.SafePlay(time, 0, false);
SetTimeButtonColors(false, true, true);
}

View file

@ -655,7 +655,7 @@ namespace HeavenStudio
if (Timeline.instance != null)
Timeline.instance?.Stop(Timeline.instance.PlaybackBeat);
else
GameManager.instance.Stop(0);
GameManager.instance.Stop(eventCaller.currentEntity.beat);
}
),
new GameAction("skill star", "Skill Star", 1f, true)

View file

@ -21,7 +21,7 @@ namespace HeavenStudio.Common
{
GameManager.instance.onSectionChange += OnSectionChange;
GameManager.instance.onBeatChanged += OnBeatChanged;
gameObject.SetActive(GameManager.instance.currentSection != null);
gameObject.SetActive(GameManager.instance.lastSection != null);
}
// Update is called once per frame
@ -32,23 +32,23 @@ namespace HeavenStudio.Common
public void OnBeatChanged(double beat)
{
gameObject.SetActive(GameManager.instance.currentSection != null);
gameObject.SetActive(GameManager.instance.lastSection != null);
SectionProgress.value = (float) GameManager.instance.SectionProgress;
}
public void OnSectionChange(RiqEntity section)
public void OnSectionChange(RiqEntity newSection, RiqEntity lastSection)
{
if (section != null)
if (newSection != null)
{
gameObject.SetActive(true);
SectionText.text = section["sectionName"];
SectionText.text = newSection["sectionName"];
SectionProgress.value = (float) GameManager.instance.SectionProgress;
if (PersistentDataManager.gameSettings.perfectChallengeType == PersistentDataManager.PerfectChallengeType.Off) return;
if (!OverlaysManager.OverlaysEnabled) return;
if (section["startPerfect"] && GoForAPerfect.instance != null && GoForAPerfect.instance.perfect && !GoForAPerfect.instance.gameObject.activeSelf)
if (newSection["startPerfect"] && GoForAPerfect.instance != null && GoForAPerfect.instance.perfect && !GoForAPerfect.instance.gameObject.activeSelf)
{
GoForAPerfect.instance.Enable(section.beat);
GoForAPerfect.instance.Enable(newSection.beat);
}
}
}

View file

@ -61,9 +61,9 @@ namespace HeavenStudio.Common
}
}
public void OnSectionChange(RiqEntity section)
public void OnSectionChange(RiqEntity newSection, RiqEntity lastSection)
{
if (section == null) return;
if (newSection == null) return;
if (!PersistentDataManager.gameSettings.isMedalOn) return;
if (PersistentDataManager.gameSettings.isMedalOn && !isMedalsStarted)
{
@ -72,19 +72,19 @@ namespace HeavenStudio.Common
}
else
{
GameManager.instance.ClearedSection = isMedalsEligible;
GameManager.instance.DoSectionCompletion(newSection.beat, isMedalsEligible, lastSection["sectionName"], 1);
GameObject medal = Instantiate(isMedalsEligible ? MedalOkPrefab : MedalMissPrefab, MedalsHolder.transform);
medal.SetActive(true);
isMedalsEligible = true;
}
}
public void OnRemixEnd()
public void OnRemixEnd(double beat, RiqEntity lastSection)
{
if (!PersistentDataManager.gameSettings.isMedalOn) return;
if (PersistentDataManager.gameSettings.isMedalOn && isMedalsStarted)
{
GameManager.instance.ClearedSection = isMedalsEligible;
GameManager.instance.DoSectionCompletion(beat, isMedalsEligible, lastSection["sectionName"], 1);
GameObject medal = Instantiate(isMedalsEligible ? MedalOkPrefab : MedalMissPrefab, MedalsHolder.transform);
medal.SetActive(true);
}

View file

@ -61,8 +61,8 @@ namespace HeavenStudio.Util
{
foreach (Util.Sound sound in playingSounds)
{
if (!sound.available)
return;
if (sound == null) continue;
if (!sound.available) return;
}
Destroy(gameObject);
}

View file

@ -19,7 +19,7 @@ namespace HeavenStudio.Util
public bool looping;
public double loopEndBeat = -1;
public double fadeTime;
int loopIndex = 0;
bool loopDone;
private AudioSource audioSource;
private Conductor cond;
@ -78,7 +78,7 @@ namespace HeavenStudio.Util
audioSource.loop = looping;
loopEndBeat = -1;
loopIndex = 0;
loopDone = false;
audioSource.Stop();
if (beat == -1 && !scheduled)
@ -87,7 +87,6 @@ namespace HeavenStudio.Util
played = true;
startTime = AudioSettings.dspTime;
audioSource.PlayScheduled(startTime);
StartCoroutine(NotRelyOnBeatSound());
}
else
{
@ -126,7 +125,6 @@ namespace HeavenStudio.Util
}
if (scheduledPitch != 0 && dspTime > scheduledTime)
{
StartCoroutine(NotRelyOnBeatSound());
played = true;
}
}
@ -140,7 +138,6 @@ namespace HeavenStudio.Util
}
if (scheduledPitch != 0 && dspTime > startTime)
{
StartCoroutine(NotRelyOnBeatSound());
played = true;
}
else
@ -171,6 +168,17 @@ namespace HeavenStudio.Util
if (played)
{
if (!(cond.isPlaying || cond.isPaused))
{
GameManager.instance.SoundObjects.Release(this);
return;
}
if (!(looping || paused || audioSource.isPlaying))
{
GameManager.instance.SoundObjects.Release(this);
return;
}
if (cond.isPaused || cond.SongPitch == 0)
{
if (!paused)
@ -191,34 +199,19 @@ namespace HeavenStudio.Util
}
}
if (loopIndex < 1)
if (!loopDone)
{
if (looping && loopEndBeat != -1) // Looping sounds play forever unless params are set.
{
if (cond.songPositionInBeatsAsDouble > loopEndBeat)
{
KillLoop(fadeTime);
loopIndex++;
loopDone = true;
}
}
}
}
IEnumerator NotRelyOnBeatSound()
{
if (!(Conductor.instance.isPlaying || Conductor.instance.isPaused))
{
GameManager.instance.SoundObjects.Release(this);
yield break;
}
WaitUntil yieldIsAudioPlaying = new WaitUntil(() => !(paused || audioSource.isPlaying || Conductor.instance.isPlaying || Conductor.instance.isPaused));
if (played && !looping) // Looping sounds are destroyed manually.
{
yield return yieldIsAudioPlaying;
GameManager.instance.SoundObjects.Release(this);
}
}
public void SetLoopParams(double endBeat, double fadeTime)
{
loopEndBeat = endBeat;
@ -248,7 +241,7 @@ namespace HeavenStudio.Util
scheduled = false;
beat = 0;
loopEndBeat = -1;
loopIndex = 0;
loopDone = false;
startTime = 0;
audioSource.loop = false;

View file

@ -37,8 +37,6 @@ namespace HeavenStudio.Util
GameObject Jukebox = new GameObject("Jukebox");
Jukebox.AddComponent<AudioSource>();
Jukebox.tag = "Jukebox";
}
if (oneShotAudioSourceObject == null)
{