publicvoidSubscribeToMuteEvents(){_events.UserMuted+= OnUserMuted;_events.UserUnmuted+= OnUserUnmuted;_events.UserSpeaking+= OnUserSpeaking;_events.UserNotSpeaking+= OnUserNotSpeaking;_events.LocalUserMuted+= OnLocalUserMuted;_events.LocalUserUnmuted+= OnLocalUserUnmuted;_events.UserCrossMuted+= OnCrossMuted;_events.UserCrossUnmuted+= OnCrossUnmuted;}publicvoidUnsubscribeToMuteEvents(){_events.UserMuted-= OnUserMuted;_events.UserUnmuted-= OnUserUnmuted;_events.UserSpeaking-= OnUserSpeaking;_events.UserNotSpeaking-= OnUserNotSpeaking;_events.LocalUserMuted-= OnLocalUserMuted;_events.LocalUserUnmuted-= OnLocalUserUnmuted;_events.UserCrossMuted-= OnCrossMuted;_events.UserCrossUnmuted-= OnCrossUnmuted;}protectedvirtualvoidOnLocalUserMuted(){Debug.Log("Local User is Muted");}protectedvirtualvoidOnLocalUserUnmuted(){Debug.Log("Local User is Unmuted");}protectedvirtualvoidOnCrossMuted(AccountId accountId){Debug.Log($"Player {accountId.DisplayName} has been Cross Muted");}protectedvirtualvoidOnCrossUnmuted(AccountId accountId){Debug.Log($"Player {accountId.DisplayName} has been Cross Unmuted");}protectedvirtualvoidOnUserMuted(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Muted : (Muted For All : {participant.IsMutedForAll})");}protectedvirtualvoidOnUserUnmuted(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Unmuted : (Muted For All : {participant.IsMutedForAll})");}protectedvirtualvoidOnUserSpeaking(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Speaking : Audio Energy {participant.AudioEnergy}");}protectedvirtualvoidOnUserNotSpeaking(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Not Speaking");}
Dynamic Events
Make sure the parameter in your method matches the event type. See what parameter is required for each User Event here. Dynamic events will dynamically invoke your method at runtime on every game object that has a dynamic event attribute. Because of this there is no need to Subscribe/Unsubscribe from events with the usual +=/-=
[UserEvent(UserStatus.LocalUserMuted)]privatevoidOnLocalUserMuted(){Debug.Log("Local User is Muted");}[UserEvent(UserStatus.LocalUserUnmuted)]privatevoidOnLocalUserUnmuted(){Debug.Log("Local User is Unmuted");}[UserEvent(UserStatus.UserCrossMuted)]privatevoidOnCrossMuted(AccountId accountId){Debug.Log($"Player {accountId.DisplayName} has been Cross Muted");}[UserEvent(UserStatus.UserCrossUnmuted)]privatevoidOnCrossUnmuted(AccountId accountId){Debug.Log($"Player {accountId.DisplayName} has been Cross Unmuted");}[UserEvent(UserStatus.UserMuted)]privatevoidOnUserMuted(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Muted : (Muted For All : {participant.IsMutedForAll})");}[UserEvent(UserStatus.UserUnmuted)]privatevoidOnUserUnmuted(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Unmuted : (Muted For All : {participant.IsMutedForAll})");}[UserEvent(UserStatus.UserSpeaking)]privatevoidOnUserSpeaking(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Speaking : Audio Energy {participant.AudioEnergy}");}[UserEvent(UserStatus.UserNotSpeaking)]privatevoidOnUserNotSpeaking(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Not Speaking");}
Dynamic Async Events
Make sure the parameter in your method matches the event type. See what parameter is required for each User Event here. Dynamic events will dynamically invoke your method at runtime on every game object that has a dynamic event attribute. Because of this there is no need to Subscribe/Unsubscribe from events with the usual +=/-=
Remember to use async void or async Task or else the event may run synchronously
More information on the methods called in any async method can be found here. Unity Gaming Services Examples. They are direct copies from Unity's docs. These are just examples and don't mimic real world use cases
[UserEventAsync(UserStatus.LocalUserMuted)]privateasyncvoidOnLocalUserMutedAsync(){Debug.Log("Local User is Muted");awaitSavePlayerData();}[UserEventAsync(UserStatus.LocalUserUnmuted)]privateasyncvoidOnLocalUserUnmutedAsync(){Debug.Log("Local User is Unmuted");awaitSavePlayerData();}[UserEventAsync(UserStatus.UserCrossMuted)]privateasyncvoidOnCrossMutedAsync(AccountId accountId){Debug.Log($"Player {accountId.DisplayName} has been Cross Muted");awaitSavePlayerData();}[UserEventAsync(UserStatus.UserCrossUnmuted)]privateasyncvoidOnCrossUnmutedAsync(AccountId accountId){Debug.Log($"Player {accountId.DisplayName} has been Cross Unmuted");awaitSavePlayerData();}[UserEventAsync(UserStatus.UserMuted)]privateasyncvoidOnUserMutedAsync(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Muted : (Muted For All : {participant.IsMutedForAll})");awaitSavePlayerData();}[UserEventAsync(UserStatus.UserUnmuted)]privateasyncvoidOnUserUnmutedAsync(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Unmuted : (Muted For All : {participant.IsMutedForAll})");awaitSavePlayerData();}[UserEventAsync(UserStatus.UserSpeaking)]privateasyncvoidOnUserSpeakingAsync(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Speaking : Audio Energy {participant.AudioEnergy}");awaitSavePlayerData();}[UserEventAsync(UserStatus.UserNotSpeaking)]privateasyncvoidOnUserNotSpeakingAsync(IParticipant participant){Debug.Log($"{participant.Account.DisplayName} Is Not Speaking");awaitSavePlayerData();}