- Home /
Synching music in multiplayer game
Hi all,
I'm making a multiplayer shooter where there is a jukebox that plays music. The music can be heard by all players, but is not in sync. Is it possible to make it so that when a player joins it syncs the audio with the other player?
I am using PUN (Photon Unity Networking) for my networking.
Here's my current code for the music player:
AudioSource audio;
public AudioClip[] playlist;
public AudioClip track1;
public AudioClip track2;
public AudioClip track3;
public AudioClip track4;
public AudioClip track5;
// Use this for initialization
void Start () {
audio = GetComponent<AudioSource> ();
playlist = new AudioClip[5];
playlist [0] = track1;
playlist [1] = track2;
playlist [2] = track3;
playlist [3] = track4;
playlist [4] = track5;
}
// Update is called once per frame
void Update () {
if (!audio.isPlaying) {
photonView.RPC ("PLAYADAMUSIC", PhotonTargets.All);
}
}
[RPC]
void PLAYADAMUSIC(){
audio.clip = playlist[Random.Range(0, 4)];
audio.Play ();
}
Answer by YoungDeveloper · Jun 02, 2015 at 02:39 AM
If you want close to 100% sync you could send a timestamp and on receive play it considering the receive delay.
Answer by Eno-Khaon · Jun 02, 2015 at 02:40 AM
I'd say start with a look at this. Your server/host can potentially know "best" at what point the music track is currently at, then tell the clients when they're in range to start the music starting at a specific point (using audio.timeSamples).
This indeed seems like the right way to do it. Though I'm not really sure how I can set the offset of the music track for each specific player when they join
Depending on the audio data rate Unity is set to (i.e. 48000kHz or 44100kHz or the like), that number multiplied by the number of seconds into the playing song is where it will be at the time.
You can get the value from the host/server through audio.timeSamples, then use a time stamp to send to the clients to tell them what (time * sample rate) to play the song from for them, setting their current time into the music using the same audio.timeSamples.
Once the latency is interpreted, it should be possible to match up the audio with reasonably great precision.
I understand what you're saying, but I'm not exactly sure how I go about doing that. Do I let my networkmanager script do all the work, or can I do this within the script of the music player?
The network manager would likely need some piece of information to distribute to other players, so it could potentially just be sent the timeSamples data from the music player, to then be distributed among other players. If the network manager isn't the exclusive source of network data, then there probably wouldn't be any reason why the music player couldn't send small bits of data itself.
In that case, however, a host/server differentiation would still be quite important when synchronization is key.
Your answer
Follow this Question
Related Questions
Audio being added to android playlist, unwanted 1 Answer
how to sync audio in instantiated object so all players can hear it? 0 Answers
how to make game object animation without animator visible to all players in photon pun? 2 Answers
Network Camera, Player 2 Answers
Audio controls disabled??! 0 Answers