When looking at the Participant Events Examples I start asking myself what the developers of these examples tried to do and whether they even tested the code. I mean, look at this switch statement of the IChannelSession.Participants.AfterValueUpdated example:
switch (property)
{
case "LocalMute":
{
if (username != accountId.Name) //can't local mute yourself, so don't check for it
{
//update their muted image
}
break;
}
case "LocalMute":
{
//update speaking indicator image
break;
}
default:
break;
}
Two times checking āLocalMuteā which in my IDE (Visual Studio 2022) gives this error (and should logically thinking also not work):
Error CS0152: The switch statement contains multiple cases with the label value āāLocalMuteāā
It baffles me how we are supposed to figure out the other valueā¦
In the BeforeKeyRemoved example I wonder about what if it is not me who gets removed from the channel. Should something be done here?
if (participant.IsSelf)
{
BindChannelSessionHandlers(false, channelSession); //Unsubscribe from events here
currentChannelID = null;
var user = client.GetLoginSession(accountId);
user.DeleteChannelSession(channelSession.Channel);
}
It may be that I have no idea how it works, but it looks kinda spooky and makes me afraid of using the SDK at all due to not being able to understand what I should use and especially how.
LOL!!! I donāt think it used to look like that but anyways. Here is what your looking for I think
ā¦ āSpeechDetectedā & not āLocalMuteā twice
private void OnUserValuesUpdated(object sender, ValueEventArg<string, IParticipant> valueArg)
{
var source = (VivoxUnity.IReadOnlyDictionary<string, IParticipant>)sender;
var senderIParticipant = source[valueArg.Key];
MyCustomEvent.OnUserValuesUpdated(senderIParticipant);
switch (valueArg.PropertyName)
{
case "LocalMute":
if (!senderIParticipant.IsSelf) //can't local mute yourself, so don't check for it
{
if (senderIParticipant.LocalMute)
{
// Fires way too much in my opinion - like every second
// fire your event / code here to change UI, etc..
}
else
{
// Fires way too much in my opinion - like every second
// fire your event / code here to change UI, etc..
}
}
break;
case "SpeechDetected":
{
if (senderIParticipant.SpeechDetected)
{
// fire your event / code here to change UI, etc..
}
else
{
// fire your event / code here to change UI, etc..
}
break;
}
default:
break;
}
As for what to do when a user leaves channel I would fire an event so you can do multiple things when this happens. For example have one method that removes the user from the UI, maybe another that notifies the user or the group that someone left, etcā¦
My version belowā¦
public class VivoxEvents()
{
private void OnUserLeftChannel(object sender, KeyEventArg<string> keyArg)
{
var source = (VivoxUnity.IReadOnlyDictionary<string, IParticipant>)sender;
var senderIParticipant = source[keyArg.Key];
MyCustomEvents.OnUserLeftChannel(senderIParticipant);
}
}
public class MyCustomEvents
{
public static Action<IParticipant> UserLeftChannel;
public static void OnUserLeftChannel(IParticipant participant)
{
UserLeftChannel?.Invoke(participant);
}
}
public class MyUI : MonoBehaviour
{
[SerializeField] Text newMessage;
void Start()
{
MyCustomEvents.UserLeftChannel += UpdateUIWhenPlayerLeaves;
}
void OnApplicationQuit()
{
MyCustomEvents.UserLeftChannel -= UpdateUIWhenPlayerLeaves;
}
void UpdateUIWhenPlayerLeaves(IParticipant participant)
{
// print message to the Text field that user has left
newMessage.text += $"\n {participant.Account.DisplayName} has left the channel";
if (!participant.IsSelf)
{
// remove UI code here
}
}
}