using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using UnityEngine; namespace HeavenStudio.Util { /// /// MultiSound that is serializable in the inspector, etc. /// [Serializable] public class SoundSequence { [Tooltip("Should sequence use game specific-sounds?")] [SerializeField] bool game; [Tooltip("Should sequence force playback even if corresponding game is not loaded?")] [SerializeField] bool force; [Tooltip("Clips to play in the sequence")] [SerializeField] private List clips = new List(); public SoundSequence(bool game, bool force, params SequenceClip[] clips) { this.game = game; this.force = force; this.clips = new List(clips); } public MultiSound Play(double startBeat, params SequenceParams[] args) { List sounds = new List(); Dictionary paramMaps = new Dictionary(); foreach (SequenceClip clipdat in clips) { string clip = clipdat.clip; double beat = clipdat.beat; float pitch = clipdat.pitch; float volume = clipdat.volume; bool looping = clipdat.looping; double offset = clipdat.offset; if (args != null && clipdat.parameters != null && clipdat.parameters.Length > 0) { paramMaps.Clear(); // map param names to overrides foreach (SequenceParams prm in clipdat.parameters) { if (!paramMaps.ContainsKey(prm.name)) paramMaps.Add(prm.name, prm.map); } // apply overrides foreach (SequenceParams prm in args) { if (paramMaps.ContainsKey(prm.name)) { string map = paramMaps[prm.name]; switch (map) { case "beat": beat = prm.value; break; case "pitch": pitch = prm.value; break; case "volume": volume = prm.value; break; case "offset": offset = prm.value; break; default: break; } } } } sounds.Add(new MultiSound.Sound(clip, startBeat + beat, pitch, volume, looping, offset)); } return MultiSound.Play(sounds.ToArray(), game, force); } [Serializable] public struct SequenceClip { [Tooltip("Filename of clip to use (will look in assetbundles before resources)")] public string clip; [Tooltip("Beat to play clip at relative to start of sequence")] public float beat; [Tooltip("Pitch to play clip at")] [DefaultValue(1f)] public float pitch; [Tooltip("Volume to play clip at")] [DefaultValue(1f)] public float volume; [Tooltip("Whether to loop the clip")] public bool looping; [Tooltip("Offset to start playing clip")] public float offset; [Tooltip("Set of possible value overrides for clip data")] public SequenceParams[] parameters; } [Serializable] public struct SequenceKeyValue { [Tooltip("Name of sequence (game scripts will call sequences to play using this name")] public string name; [Tooltip("Sequence to play")] public SoundSequence sequence; } [Serializable] public struct SequenceParams { //SequenceParams used in minigame code public SequenceParams(string name, float value) { this.map = ""; this.name = name; this.value = value; } [Tooltip("Inspector use only; Sequence Clip value to override")] public string map; [Tooltip("Name of parameter")] public string name; [NonSerialized] public float value; } } }