Is there a way to give a playing sound multiple tags?
tl;dr (preemptively) - C2 doesn't support this as far as I can tell, and I have a partial solution but its got issues, so I figured it was worth asking.
I'm looking to create a tag system for audio, such that when I play a sound, I can add multiple tags to that sound, allowing later access to all currently playing sounds that share a given tag, like "ambiance" or "water".
Presently the C2 Audio object allows you to specify a "tag" when playing a sound, but you can only provide a single string. And you can only lookup playing sounds by matching that exact string. So I couldn't, for instance, get a list of all playing sounds with tags containing the substring "ambiance" or "water".
Why I'm interested:
There are a few reasons.
More flexible interaction with sounds:
I would like to be able to access a playing sound by either its exact name ("footStep03"), or by its sample-set name ("footStep"), or by its category ("player"). Likewise, it would be nice to be able to trigger "On ended" events in response to sounds with specific tags.
More flexible Menu control over sounds:
I'd like to be able to make an audio menu with volume sliders for different categories of sound, for instance "Music", "Voice", "Ambience", "Sound effects", and "User interface". In particular, for sounds that are currently playing, like any actively looping ambience, adjusting the slider in the menu would need to affect the sounds while they were playing, rather than "next time" they get played.
My current partial solution:
So far I've got something that sort of works, but with some ugly side effects.
I'm using a custom "playSound" function I created via the function object. The function will play a sound and tag it with a unique numeric ID, that increments with each call. At the same time, a key with that same ID will be added to a dictionary, and the associated value will be a comma separated list of the tag strings I want to attach to that sound.
This allows me to access playing sounds by looping through the dictionary and searching for specific tag strings in the values. Each value is tokenized (comma delimited) into individual tag strings. Because each key links back to a single unique sound, this system can map an arbitrary number of tag strings to individual playing sounds.
There is a problem, though. I can't trigger the removal of a sound entry from the dictionary when the sounds stops playing. The reason is that there is no way to use the "On ended" event generically, as C2 requires you to name the exact tag of the sound that is ending. I would need to check to see if *any* sound is ending, and then remove the ending sound's dictionary entry in response. (You can do this kind of generic detection with the Keyboard object, and the Gamepad object, but not the Audio object.)
I can't quite use System Wait with the duration of the sound as the wait time, because System Wait is slaved to the timescale, so I could get weird behavior whenever the game was paused.
I could potentially save the expected end time in a 2nd timeout dictionary, and every few seconds loop through it to see if any entry's time is up. Basically periodic garbage collection. Though that seems a bit ugly, and might cause a periodic performance hit. Maybe not, I don't know.
"On ended" inside a loop:
One weird possibility that might work, depending on how C2 handles loops and triggered events, is to create a "For Each Key" loop and then use that to check every key (sound ID) in the "On ended" event, every tick. I don't think that should work if the "On ended" event is a true triggered event, but if it's a "fake" triggered event (as described in the C2 plugin SDK documentation) then it might. Even if it does, that doesn't sound very efficient.
I could suggest multiple tags for audio as a feature. I think it would be pretty handy, but I have no idea if interest would be wide spread enough to make it a worthwhile implementation.
Mod Audio object:
This is what I looking into now. Building a modified version of the Audio plugin. The downside is that my modified version would not get updated with the rest of C2, and that would probably become a bigger and bigger problem as time goes on.
If you got this far, I appreciate you taking your time to read through this, sorry about the length.
Thanks in advance for any replies, and any suggestions are welcome.