Audiokinetic's Community Q&A is the forum where users can ask and answer questions within the Wwise and Strata communities. If you would like to get an answer from Audiokinetic's Technical support team, make sure you use the Support Tickets page.

+5 votes
Hi All,

 

can someone explain me how to check if a Event is playing in Unity? We're using Unity 2018.1.1 and correlated Wwise integration. I can't find how to check this situation.

Kind regards
in General Discussion by Loris C. (180 points)
I just came here to ask the same question after searching hours for an answer.  Weird you can't find basic stuff like this in the docs, or anywhere else.
Since there seems to be no answer to this question, I had to implement my own state flags.  The looping events are easy enough by setting an extra flag when posting and stopping.  The one-offs are a bit more involved requiring a callback on EndOfEvent just to turn the flag off.  I suppose I could create a wrapper class if I really wanted to.  But, very very strange I have to add play state to someone else's audio object.  Isn't that what people want to know first about audio?
Hope no, because for my project make a state machine that will check if the events are playing will be very pity and frustrating (we're making a comic book app and some events plays for many pages and others only for one). Maybe, as i was thinking with my developer, wwise manage it in a very different way but it's not clear from the documentation.

2 Answers

+3 votes

I got some help in a Facebook group on how to use GetPlayingIDsFromGameObject and here is what I came up with to test if an event is playing on a certain GameObject. It's tricky because GetPlayingIDsFromGameObject needs an array of exactly the right size in order to work (for whatever reason), hence why we call that function twice. Creating a new array every time you call the function is a bit concerning. Anywho, hope this is useful to someone.

 

static uint[] playingIds = new uint[50];

public static bool IsEventPlayingOnGameObject(string eventName, GameObject go)
{
    uint testEventId = AkSoundEngine.GetIDFromString(eventName);

    uint count = playingIds.length;
    AKRESULT result = AkSoundEngine.GetPlayingIDsFromGameObject(go, ref count, playingIds);

    for (int i = 0; i < count; i++)
    {
        uint playingId = playingIds[i];
        uint eventId = AkSoundEngine.GetEventIDFromPlayingID(playingId);

        if (eventId == testEventId)
            return true;
    }

    return false;
}

EDIT: I updated the code snippet.

After playing around some more and re-reading the documentation, I discovered that it is not necessary to have an array of precisely the correct length. The important thing is that count is both an input and an output from the function. count should not be 0 but rather be the length of the array playingIds. after the function returns, count will be the number of ids plopped into playingIds. No need to call the function twice or make a new array each time the function is called.

So the mistake was setting count=0 which told the function that our array had a length of 0 and therefore it couldn't plop any ids into it.

I think my confusion stemmed from the difference in conventions between C++ and C#. In C++ the array is a pointer and doesn't pass any information about its length. In C# you can always get the length of an array, which is why this seems like a weird way to do things.

EDIT 23 May 2020: added instantiation of result and playingIds to the code snippet.

by Simon S. (280 points)
edited by Simon S.
Hi, I'm kinda lost on the code you posted, where does the playingIds and result variable get made at? I'm noticing all the other variables in the method get instantiated in the method, however, I can't make count equal to playingIds.length if I never make a playingIds variable, that also applies to the result variable
True,
that should be "AKRESULT result = ..."
and i instantiate playingIds in the class. "static uint[] playingIds = new uint[50];"
I put 50 because we don't play that many events simultaneously in our game.
Can't seem to find this function "GetPlayingIDsFromGameObject". Is it only available for Unity? I'm using Unreal plugin 2019.1.7
Awesome, thank you!
+1 vote
Hey thought I'd share this if anyone has trouble with this too. Wwise actually has a great tutorial on this that talks about how to use callbacks https://www.audiokinetic.com/courses/wwise301/?source=wwise301&id=Callbacks_on_a_WwiseType_Event.

Although frustratingly there isn't a callback for when a standard event is played only for music events.

But there is a CallBacktType called EventEnded.

In my case, I had a voiceover that I didn't want to play while a different voiceover was playing.  

So for me, I just made a bool that I set true after the event is posted then when the Event is ended I just set that bool false. Then I can use that bool in an If statement to check if the sound is playing or not.

The only problem with this solution would be using the bool in Update. If you wanted it in Update you'd just have to make sure it plays once, so use another bool.

Although I personally try to avoid putting events in Update. I don't think it's very performant.

public class W_CallbackExample : MonoBehaviour
{
    public AK.Wwise.Event sound;
    bool isSoundPlaying;
    void Start()
    {
        sound.Post(gameObject, (uint)AkCallbackType.AK_EndOfEvent, CallBackFunction);
        isSoundPlaying = true;
    }
    void CallBackFunction(object in_cookie, AkCallbackType callType, object in_info)
    {
        if (callType == AkCallbackType.AK_EndOfEvent)
        {
            isSoundPlaying = false;
        }
    }
    void PlayOtherSound()
    {
        if (!isSoundPlaying)
        {
            AkSoundEngine.PostEvent("Sound2", gameObject);
        }
    }
by Kyan R. (160 points)
...