I'm working through the next phase of a multiplayer VR experience using the Meta Avatars2 SDK and Photon. I'm struggling to understand a key concept. That is, how to load the remote users Avatar.
My current process is this:
1) First player joins the room/experience. The "OnJoinedRoom" callback is fired which instantiates the NetworkPlayer prefab.
2) Attached to this NetworkPlayer prefab is a modified version of the SampleAvatarEntity.cs script that comes with the examples. It extends the AvatarEntity class and I override Awake so that I can configure the creationInfo features, set the avatar as local or not, depending on PhotonView.IsMine, etc.
3) In Start() I call LoadCdnAvatar(). This successfully loads my avatar and I am displayed correctly.
4) Ultimately we receive a _userId from Oculus which identifies my avatar. I store this value so that I can pass it over the network in the future to other instances of my player that are generated when other players join.
5) The next player joins the room/experience at this point. Essentially the process is the same as steps 1-4 above.
6) When we get the new users _userId we call an RPC function that passes the id to all other instances of this player on the network. Potential problem: This may be passed to the other instances on the network before the other Avatars have been created. This may be an issue.
6) Additionally, the "OnPlayerEnteredRoom" function is called for the first player. At this time we call an RPC on the first users PhotonView to pass the previously captured OculusId (in step 4) to all other instances of this player on the network. Potential problem: This may be passed to the other instances on the network before the other Avatars have been created. This may be an issue.
This is where things get weird. If I'm the first player in the experience, when the second player joins I am receiving the OculusId from the second user and it is loading the remote avatar correctly. However, it's also updating MY avatar to look like the remote user. Which is strange because the ID is passed via an RPC call on the remote users avatar only. So only the PhotonView on the clone of the second player should be receiving this.
When the second player joins the room, and the Avatar is instantiated, it too is calling the LoadCdnAvatar() at the start. So initially, the remote users avatar looks just like me, which makes sense, I'm loading my own avatar again to start. And then when we receive the OculusId from the RPC call and we call the LoadRemoteUserCdnAvatar() function. Which for some reason is updating both Avatars to look like the remote user!
1) Are these two avatars synced up somehow because I loaded my own avatar into both of them? Only my local avatar has the AvatarSDKManagerHorizon object defined. I leave this blank for remote users.
2) I've logged my other developers OculusId. But I can only load his ID when he is also loaded into the app. I'm assuming Oculus is checking if the user associated with an ID is logged in with a token before allowing me to load their avatar?
3) Is this the correct process? To load my own avatar into the remote users entity at first and then replace it with their avatar once I receive their ID over the network?
Thanks for any help anyone can offer! 🙂
I just found an answer to my question #2 above and wanted to share. I changed my process to pass the oculusID in the Pun InstantiationData instead, so that we have the id when the entity is created and it worked! My other developer wasn't on the app but I passed his oculusID manually and it loaded his avatar. So no, the user does not have to be logged in to load their avatar 🙂
I'm waiting to test this afternoon to see if I've fixed #1 and #3. I'll report back in case it helps anyone else in the future.
It worked! I changed our workflow completely. On startup the local user is loaded and the Avatar ID is stored at that time. When they join the experience we pass the Avatar ID in the Photon Instantiation Data and load the avatar that way. We were approaching this wrong at the start.
Thanks, @j0schm03 for your question and answer. It's really helpful.
I have some questions. Let's consider Player1 and Player2.
When Player 1 joined the game, save the UserID of player1. After Player2 joins, we have to pass that Player1 userID in-network to instantiate so, the actual avatar of Player1 will be visible to player2. Am I correct?
Can you please let me know what changes you have done in SampleAvatarEntity_cs, I understood one is in Awake you have set IsLocal as per pv.isMine or not. Any else changes have you done? Where to pass UserID of the remote avatar inSampleAvatarEntity_cs script?
I ended up scraping the sampleavatarentity script all together. Check out this thread here: https://forums.oculusvr.com/t5/Unity-VR-Development/Meta-avatar-2-multiplayer/m-p/942968/highlight/t... the code sample there got me working!