cancel
Showing results for 
Search instead for 
Did you mean: 

Multiplayer App Background Music Syncing

Anonymous
Not applicable
I'm developing a multiplayer VR app in Unity with Photon. I want to have background music which is in sync for all players. But what's happening with what I've tried so far is that the music starts from the beginning for each player as they enter the game. So for example if the first player to enter is at 30" into the music (having started at 0"), the music will continue playing from 30" for the first player but from 0" for the second player. Instead I want the music to be playing at 30" (or whatever the time is for the first player) when the second player (and third and fourth, etc.) enters.  Can anyone assist?
4 REPLIES 4

MikeF
Level 10
How are you trying to sync this currently?

Anonymous
Not applicable
Sorry I didn't respond sooner, MikeF.  My latest attempt involved having the game object with the audio source/music clip with a Photon View instantiated by the first player to enter the game.  But it still starts at 0" whenr the second player enters.

MikeF
Level 10
So youve got the setup correct but you still need to sync the data contained within the object once the 2nd player joins.
Basic flow should be something like this:
1) session starts with master client, audio starts playing
2) 2nd player joins
3) master client sends rpc containing current time of audio clip playback
4) 2nd player recieves rpc, sets start time of the audio clip to match the recieved time stamp and begins playing

Id suggest using the onPhotonPlayerConnected() callback to initiate the rpc and target it towards the newly connected player so that anyone else in the room isnt affected by the sync since theres likely to be a small delay caused by network latency which would cause a small hitch in the audio for players that have already been synced

Anonymous
Not applicable
Thanks for your input, MikeF.  I should say I'm kind of a newbie at coding and Photon.  Someone named JLF responded to the same post as this one on the Unity forum.  He provided code which works to sync music in a single player game, but he's never worked with Photon.  JLF's code is here: https://forum.unity.com/threads/multiplayer-app-background-music-syncing.767105/
I've tried unsuccessfully to adapt his code into a script which uses Photon.  The problem I'm having is how to get the "firstStartTime" variable (as I understand it, the time in the game the music starts for the first player) to later players.  My script (which doesn't work) is attached to the player prefab and is copied below.  My current set up is not to have the first player instantiate an audio source/music clip object; rather, that object is attached to the player prefab.  If you could point me in the right direction I'd really appreciate it!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using TMPro;
using Photon.Realtime;
public class DWM_PlayerSetup : MonoBehaviourPunCallbacks
{
    [SerializeField] GameObject centerEyeAnchor;
    [SerializeField] GameObject bulletStartPos;
    [SerializeField] GameObject audioSourceObject;
    [SerializeField] TextMeshProUGUI playerNameText;
    // Per JLF script:
    public AudioSource audioSource;
    public double firstStartTime;
    public double clipLength;
    public int sampleRate;
    void Start()
    {
        //Per JLF script:
        clipLength = GetClipLength();
        // DWM:
        if (PhotonNetwork.CurrentRoom.PlayerCount == 1)
            photonView.RPC("StartMusic", RpcTarget.AllBuffered);
        //else
            //photonView.RPC("StartMusicWithDelay", RpcTarget.AllBuffered);
        if (photonView.IsMine == false)
        {
            transform.GetComponent<DWM_FPControllerVRAllPurpose3DII>().enabled = false;
            bulletStartPos.GetComponent<DWM_Shoot>().enabled = false;
            centerEyeAnchor.SetActive (false);
            audioSourceObject.SetActive(false);
        }
        SetPlayerUI();
    }
    void SetPlayerUI()
    {
        if (playerNameText != null)
        {
            playerNameText.text = photonView.Owner.NickName;
            Debug.Log("Player has been named. - DWM");
        }
    }
    // Per JLF script:
    double GetClipLength()
    {
        sampleRate = audioSource.clip.frequency;
        double length = (double)audioSource.clip.samples / sampleRate;
        return length;
    }
    [PunRPC]
    void StartMusic()
    {
        firstStartTime = AudioSettings.dspTime + 1;
        audioSource.PlayScheduled(firstStartTime);
    }
    public override void OnPlayerEnteredRoom(Player newPlayer)
    {
        gameObject.GetComponent<PhotonView>().RPC("StartMusicWithDelay", RpcTarget.OthersBuffered, firstStartTime);
    }
    [PunRPC]
    public void StartMusicWithDelay()
    {
            double scheduledStartTime = AudioSettings.dspTime + 1;
            double timeSinceStart = (scheduledStartTime - firstStartTime) % clipLength;
            int samplePosition = (int)(sampleRate * timeSinceStart);
            audioSource.timeSamples = samplePosition;
            audioSource.PlayScheduled(scheduledStartTime);
    }
}