using System; using System.Collections.Generic; using System.Reflection; using Ichni.RhythmGame.Beatmap; using SLSUtilities.WwiseAssistance; namespace Ichni.RhythmGame { public partial class NoteAudioSubmodule : SubmoduleBase { #region Audio Settings public List generalJudgeAudioList; public List perfectAudioList; public List goodAudioList; public List badAudioList; public List missAudioList; public List holdStartAudioList; public List holdLoopAudioList; public List holdEndAudioList; #endregion #region GC-Free Wwise IDs private uint[] _generalJudgeAudioIds; private uint[] _perfectAudioIds; private uint[] _goodAudioIds; private uint[] _badAudioIds; private uint[] _missAudioIds; private uint[] _holdStartAudioIds; private uint[] _holdEndAudioIds; private NoteBase note => attachedGameElement as NoteBase; #endregion #region Initialization public NoteAudioSubmodule(NoteBase attachedGameElement, string defaultAudio) : base(attachedGameElement) { generalJudgeAudioList = new List { defaultAudio }; perfectAudioList = new List(); goodAudioList = new List(); badAudioList = new List(); missAudioList = new List(); holdStartAudioList = new List(); holdLoopAudioList = new List(); holdEndAudioList = new List(); if (!HaveSameSubmodule) { note.NoteAudioSubmodule = this; } InitializeAudio(); } public NoteAudioSubmodule(NoteBase attachedGameElement, List generalJudgeAudioList, List perfectAudioList, List goodAudioList, List badAudioList, List missAudioList, List holdStartAudioList, List holdLoopAudioList = null, List holdEndAudioList = null) : base(attachedGameElement) { this.generalJudgeAudioList = generalJudgeAudioList ?? new List(); this.perfectAudioList = perfectAudioList ?? new List(); this.goodAudioList = goodAudioList ?? new List(); this.badAudioList = badAudioList ?? new List(); this.missAudioList = missAudioList ?? new List(); this.holdStartAudioList = holdStartAudioList ?? new List(); this.holdLoopAudioList = holdLoopAudioList ?? new List(); this.holdEndAudioList = holdEndAudioList ?? new List(); if (!HaveSameSubmodule) { note.NoteAudioSubmodule = this; } InitializeAudio(); } public void InitializeAudio() { _generalJudgeAudioIds = ParseWwiseEventIDs(generalJudgeAudioList); _perfectAudioIds = ParseWwiseEventIDs(perfectAudioList); _goodAudioIds = ParseWwiseEventIDs(goodAudioList); _badAudioIds = ParseWwiseEventIDs(badAudioList); _missAudioIds = ParseWwiseEventIDs(missAudioList); _holdStartAudioIds = ParseWwiseEventIDs(holdStartAudioList); _holdEndAudioIds = ParseWwiseEventIDs(holdEndAudioList); } private uint[] ParseWwiseEventIDs(List audioNames) { if (audioNames == null || audioNames.Count == 0) return Array.Empty(); List ids = new List(audioNames.Count); Type eventsType = typeof(AK.EVENTS); for (int i = 0; i < audioNames.Count; i++) { if (string.IsNullOrEmpty(audioNames[i])) continue; string upperName = audioNames[i].ToUpper(); FieldInfo field = eventsType.GetField(upperName, BindingFlags.Public | BindingFlags.Static); if (field != null) { ids.Add((uint)field.GetValue(null)); } else { UnityEngine.Debug.LogWarning($"[Wwise] AK.EVENTS does not contain event name: {upperName}"); } } return ids.ToArray(); } #endregion } #region Audio Playback Methods public partial class NoteAudioSubmodule { public void PlayHoldStartAudio() { PlayAudioInternal(_holdStartAudioIds); } public void PlayHoldEndAudio() { if (_holdEndAudioIds != null && _holdEndAudioIds.Length > 0) { PlayAudioInternal(_holdEndAudioIds); return; } PlayGeneralJudgeAudios(); } public void PlayGeneralJudgeAudios() { PlayAudioInternal(_generalJudgeAudioIds); } public void PlayNoteJudgeAudios(NoteBase.NoteJudgeType judgeType) { switch (judgeType) { case NoteBase.NoteJudgeType.Perfect: PlayAudioInternal(_perfectAudioIds); break; case NoteBase.NoteJudgeType.Good: PlayAudioInternal(_goodAudioIds); break; case NoteBase.NoteJudgeType.Bad: PlayAudioInternal(_badAudioIds); break; case NoteBase.NoteJudgeType.Miss: PlayAudioInternal(_missAudioIds); break; } } private void PlayAudioInternal(uint[] audioIds) { if (audioIds == null) return; for (int i = 0; i < audioIds.Length; i++) { AkSoundEngine.PostEvent(audioIds[i], AudioManager.Instance.gameObject); } } } #endregion #region Beatmap #endregion }