0
\$\begingroup\$

I am creating a system in Unity using Mirror Networking which will only require one host/server and one client. It is a WebGL build so the client will connect on a browser. I want to send commands from the server to play audio clips on the client without the client being able to control anything. The audio is questions an avatar is asking the user. Due to another constraint (Lip Sync setup) I have one AudioSource and one long audio clip which contains all the questions and is played by pressing the space bar. So rather than playing each audio clip separately, the audio clip is unpaused and paused. It will pause itself after a set time when the question line is finished and then I press the enter key to unpause the AudioSource for the next question (and again, each line will pause itself after a set time which is the length of the individual question).

Before I added Mirror or any networking component to the project this worked fine in WebGL, but now the audio will not behave the same. I tried it in Google Chrome and Microsoft Edge. It will play/unpause when I press the space/enter keys and it will pause but after the first two lines (which play correctly) it will start to skip ahead a few seconds every time I unpause it. I used the WebGL development build to check that the AudioSource.time is correct before it is unpaused but it still will play the wrong part of the audioclip. It almost seems like the audio clip is still running even after it has been paused because the longer I wait the further into the clip it will play, but it is not a direct second:second relationship, even if I play lines closely after each other it seems to skip ahead further and further each time.

In this Networking case are there two different AudioSources (One for the server and one for the client)? Though how could the debug log show the correct AudioSource.time (in Unity editor and the browser) but then it is unpaused at a different time? Is the client version of the AudioSource running in the background so the time is increasing even though the audio has been paused? It doesn't make sense to me but I am quite new to Unity, especially Mirror and network programming in general. Or could this be some issue with WebGL? I think it probably isn't solely a WebGL issue since this part was working in WebGL before I added any networking component to the project.

When I build it as a Windows project instead of WebGL, it works perfectly. So I am unsure if it is an issue with my networking code. Could it be an issue specifically caused by using Mirror or networking with a WebGL build?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;

public class SoundTracker : NetworkBehaviour
{
    public AudioSource soundFX;
    public int count = 0;

    // Update is called once per frame
    void Update()
    {
        if (isServer != true) return;

        if (Input.GetKeyDown(KeyCode.Space))
        {
            count = 0;
            startSound();
            StartCoroutine(SoundWaiter(33.5f));
        }

        if (Input.GetKeyDown(KeyCode.Return))
        {
            float[] lineDurations = { 3.2f, 4.75f, 4.5f, 5f, 4f, 5.5f, 5.5f, 3.8f, 8.6f, 2.9f };
            playSound();
            StartCoroutine(SoundWaiter(lineDurations[count]));
            count = count + 1;
        }
    }

    [Server]
    IEnumerator SoundWaiter(float duration)
    {
        yield return new WaitForSeconds(duration);
        pauseSound();
    }

    [ClientRpc]
    void startSound()
    {
        soundFX.Play();
    }

    [ClientRpc]
    void playSound()
    {
        soundFX.UnPause();
    }

    [ClientRpc]
    void pauseSound()
    {
        soundFX.Pause();
    }
}

```
\$\endgroup\$
10
  • 1
    \$\begingroup\$ Where do you actually pause on the client? \$\endgroup\$
    – Zibelas
    Nov 20 at 16:03
  • \$\begingroup\$ Oh, so the SoundWaiter() allows the line to finish then pauses it on the server but since I cannot make an IEnumerator function a [ClientRpc] (I tried), it never gets paused on the client. So I should add a function call in SoundWaiter() that calls another [ClientRpc] function to pause the sound on the client. \$\endgroup\$
    – Michael
    Nov 20 at 16:21
  • \$\begingroup\$ Thanks for pointing that out. If you want to make an answer I will accept it as the solution once I can. \$\endgroup\$
    – Michael
    Nov 20 at 16:22
  • \$\begingroup\$ I added a [ClientRpc] pauseSound() function which pauses soundFX and it is called by SoundWaiter, rebuilt the project but I am still having the same issue. \$\endgroup\$
    – Michael
    Nov 20 at 16:33
  • \$\begingroup\$ There is another error. Check the documentation of mirror for the attributes. mirror-networking.gitbook.io/docs/manual/guides/attributes Basically [Server] means, it can only run on the server. But to actually call the function, you need [Command] \$\endgroup\$
    – Zibelas
    Nov 20 at 16:56

1 Answer 1

0
\$\begingroup\$

I am still unsure exactly why Mirror Networking behaves differently with WebGL than the Windows build in this situation (I am using the simple web transport which is recommended for working with WebGL) but I managed to find a work-around for this situation.

If I set AudioSource.time to the starting time of each audio line before unpausing, I am able to play it line by line rather than it not pausing and running in the background in the client.

Thanks a lot to @Zibelas who helped improve my understanding of what was going on with the networking code and narrowing down the issue.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;

public class SoundTracker : NetworkBehaviour
{
    public AudioSource soundFX;
    public int count = 0;
    float timeStamp = 0;

    // Update is called once per frame
    void Update()
    {
        if (isServer != true) return;

        if (Input.GetKeyDown(KeyCode.Space))
        {
            count = 0;
            startSound();
            StartCoroutine(SoundWaiter(33.5f));
        }

        if (Input.GetKeyDown(KeyCode.Return))
        {
            float[] lineDurations = { 3.2f, 4.75f, 4.5f, 5f, 4f, 5.5f, 5.5f, 3.8f, 8.6f, 2.9f };
            timeStamp = 33.5f;
            for (int i = 0; i < count; i++)
            {
                timeStamp = timeStamp + lineDurations[i];
            }
            playSound(timeStamp);
            StartCoroutine(SoundWaiter(lineDurations[count]));
            count = count + 1;
        }
    }

    [Server]
    IEnumerator SoundWaiter(float duration)
    {
        yield return new WaitForSeconds(duration);
        pauseSound();
    }

    [ClientRpc]
    void startSound()
    {
        soundFX.time = 0;
        soundFX.Play();
    }

    [ClientRpc]
    void playSound(float startTime)
    {
        soundFX.time = startTime;
        soundFX.UnPause();
    }

    [ClientRpc]
    void pauseSound()
    {
        soundFX.Pause();
    }
}
```
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .