2022-06-29 14:45:17 +03:00

424 lines
16 KiB
C#

// ----------------------------------------------------------------------------
// <copyright file="VoiceDemoUI.cs" company="Exit Games GmbH">
// Photon Voice Demo for PUN - Copyright (C) Exit Games GmbH
// </copyright>
// <summary>
// UI manager class for the PUN Voice Demo
// </summary>
// <author>developer@photonengine.com</author>
// ----------------------------------------------------------------------------
using System;
using Photon.Voice.Unity;
using Photon.Voice.PUN;
#pragma warning disable 0649 // Field is never assigned to, and will always have its default value
namespace ExitGames.Demos.DemoPunVoice
{
using Photon.Pun;
using UnityEngine;
using UnityEngine.UI;
using Client.Photon;
#if !UNITY_EDITOR && UNITY_PS4
using Sony.NP;
#elif !UNITY_EDITOR && UNITY_SHARLIN
using System.Runtime.InteropServices;
#endif
public class VoiceDemoUI : MonoBehaviour
{
#if !UNITY_EDITOR && UNITY_SHARLIN
[DllImport("PhotonVoiceLocalUserIDPlugin")]
private static extern int egpvgetLocalUserID(); // returns the user ID of the user at index 0 in the list of local users
#endif
[SerializeField]
private Text punState;
[SerializeField]
private Text voiceState;
private PhotonVoiceNetwork punVoiceNetwork;
private Canvas canvas;
[SerializeField]
private Button punSwitch;
private Text punSwitchText;
[SerializeField]
private Button voiceSwitch;
private Text voiceSwitchText;
[SerializeField]
private Button calibrateButton;
private Text calibrateText;
[SerializeField]
private Text voiceDebugText;
public Recorder recorder;
[SerializeField]
private GameObject inGameSettings;
[SerializeField]
private GameObject globalSettings;
[SerializeField]
private Text devicesInfoText;
private GameObject debugGO;
private bool debugMode;
private float volumeBeforeMute;
private DebugLevel previousDebugLevel;
public bool DebugMode
{
get
{
return this.debugMode;
}
set
{
this.debugMode = value;
this.debugGO.SetActive(this.debugMode);
this.voiceDebugText.text = String.Empty;
if (this.debugMode)
{
this.previousDebugLevel = this.punVoiceNetwork.Client.LoadBalancingPeer.DebugOut;
this.punVoiceNetwork.Client.LoadBalancingPeer.DebugOut = DebugLevel.ALL;
}
else
{
this.punVoiceNetwork.Client.LoadBalancingPeer.DebugOut = this.previousDebugLevel;
}
if (DebugToggled != null)
{
DebugToggled(this.debugMode);
}
}
}
public delegate void OnDebugToggle(bool debugMode);
public static event OnDebugToggle DebugToggled;
[SerializeField]
private int calibrationMilliSeconds = 2000;
private void Awake()
{
this.punVoiceNetwork = PhotonVoiceNetwork.Instance;
}
private void OnEnable()
{
ChangePOV.CameraChanged += this.OnCameraChanged;
BetterToggle.ToggleValueChanged += this.BetterToggle_ToggleValueChanged;
CharacterInstantiation.CharacterInstantiated += this.CharacterInstantiation_CharacterInstantiated;
this.punVoiceNetwork.Client.StateChanged += this.VoiceClientStateChanged;
PhotonNetwork.NetworkingClient.StateChanged += this.PunClientStateChanged;
}
private void OnDisable()
{
ChangePOV.CameraChanged -= this.OnCameraChanged;
BetterToggle.ToggleValueChanged -= this.BetterToggle_ToggleValueChanged;
CharacterInstantiation.CharacterInstantiated -= this.CharacterInstantiation_CharacterInstantiated;
this.punVoiceNetwork.Client.StateChanged -= this.VoiceClientStateChanged;
PhotonNetwork.NetworkingClient.StateChanged -= this.PunClientStateChanged;
}
private void CharacterInstantiation_CharacterInstantiated(GameObject character)
{
if (this.recorder) // probably using a global recorder
{
return;
}
PhotonVoiceView photonVoiceView = character.GetComponent<PhotonVoiceView>();
if (photonVoiceView.IsRecorder)
{
this.recorder = photonVoiceView.RecorderInUse;
}
}
private void InitToggles(Toggle[] toggles)
{
if (toggles == null) { return; }
for (int i = 0; i < toggles.Length; i++)
{
Toggle toggle = toggles[i];
switch (toggle.name)
{
case "Mute":
toggle.isOn = AudioListener.volume <= 0.001f;
break;
case "VoiceDetection":
toggle.isOn = this.recorder != null && this.recorder.VoiceDetection;
break;
case "DebugVoice":
toggle.isOn = this.DebugMode;
break;
case "Transmit":
toggle.isOn = this.recorder != null && this.recorder.TransmitEnabled;
break;
case "DebugEcho":
toggle.isOn = this.recorder != null && this.recorder.DebugEchoMode;
break;
case "AutoConnectAndJoin":
toggle.isOn = this.punVoiceNetwork.AutoConnectAndJoin;
break;
case "AutoLeaveAndDisconnect":
toggle.isOn = this.punVoiceNetwork.AutoLeaveAndDisconnect;
break;
}
}
}
private void BetterToggle_ToggleValueChanged(Toggle toggle)
{
switch (toggle.name)
{
case "Mute":
//AudioListener.pause = toggle.isOn;
if (toggle.isOn)
{
this.volumeBeforeMute = AudioListener.volume;
AudioListener.volume = 0f;
}
else
{
AudioListener.volume = this.volumeBeforeMute;
this.volumeBeforeMute = 0f;
}
break;
case "Transmit":
if (this.recorder)
{
this.recorder.TransmitEnabled = toggle.isOn;
}
break;
case "VoiceDetection":
if (this.recorder)
{
this.recorder.VoiceDetection = toggle.isOn;
}
break;
case "DebugEcho":
if (this.recorder)
{
this.recorder.DebugEchoMode = toggle.isOn;
}
break;
case "DebugVoice":
this.DebugMode = toggle.isOn;
break;
case "AutoConnectAndJoin":
this.punVoiceNetwork.AutoConnectAndJoin = toggle.isOn;
break;
case "AutoLeaveAndDisconnect":
this.punVoiceNetwork.AutoLeaveAndDisconnect = toggle.isOn;
break;
}
}
private void OnCameraChanged(Camera newCamera)
{
this.canvas.worldCamera = newCamera;
}
private void Start()
{
this.canvas = this.GetComponentInChildren<Canvas>();
if (this.punSwitch != null)
{
this.punSwitchText = this.punSwitch.GetComponentInChildren<Text>();
this.punSwitch.onClick.AddListener(this.PunSwitchOnClick);
}
if (this.voiceSwitch != null)
{
this.voiceSwitchText = this.voiceSwitch.GetComponentInChildren<Text>();
this.voiceSwitch.onClick.AddListener(this.VoiceSwitchOnClick);
}
if (this.calibrateButton != null)
{
this.calibrateButton.onClick.AddListener(this.CalibrateButtonOnClick);
this.calibrateText = this.calibrateButton.GetComponentInChildren<Text>();
}
if (this.punState != null)
{
this.debugGO = this.punState.transform.parent.gameObject;
}
this.volumeBeforeMute = AudioListener.volume;
this.previousDebugLevel = this.punVoiceNetwork.Client.LoadBalancingPeer.DebugOut;
if (this.globalSettings != null)
{
this.globalSettings.SetActive(true);
this.InitToggles(this.globalSettings.GetComponentsInChildren<Toggle>());
}
if (this.devicesInfoText != null)
{
if (UnityMicrophone.devices == null || UnityMicrophone.devices.Length == 0)
{
this.devicesInfoText.enabled = true;
this.devicesInfoText.color = Color.red;
this.devicesInfoText.text = "No microphone device detected!";
}
else if (UnityMicrophone.devices.Length == 1)
{
this.devicesInfoText.text = string.Format("Mic.: {0}", UnityMicrophone.devices[0]);
}
else
{
this.devicesInfoText.text = string.Format("Multi.Mic.Devices:\n0. {0} (active)\n", UnityMicrophone.devices[0]);
for (int i = 1; i < UnityMicrophone.devices.Length; i++)
{
this.devicesInfoText.text = string.Concat(this.devicesInfoText.text, string.Format("{0}. {1}\n", i, UnityMicrophone.devices[i]));
}
}
}
#if !UNITY_EDITOR && UNITY_PS4
UserProfiles.LocalUsers localUsers = new UserProfiles.LocalUsers();
UserProfiles.GetLocalUsers(localUsers);
int userID = localUsers.LocalUsersIds[0].UserId.Id;
punVoiceNetwork.PlayStationUserID = userID;
#elif !UNITY_EDITOR && UNITY_SHARLIN
punVoiceNetwork.PlayStationUserID = egpvgetLocalUserID();
#endif
}
private void PunSwitchOnClick()
{
if (PhotonNetwork.NetworkClientState == Photon.Realtime.ClientState.Joined)
{
PhotonNetwork.Disconnect();
}
else if (PhotonNetwork.NetworkClientState == Photon.Realtime.ClientState.Disconnected ||
PhotonNetwork.NetworkClientState == Photon.Realtime.ClientState.PeerCreated)
{
PhotonNetwork.ConnectUsingSettings();
}
}
private void VoiceSwitchOnClick()
{
if (this.punVoiceNetwork.ClientState == Photon.Realtime.ClientState.Joined)
{
this.punVoiceNetwork.Disconnect();
}
else if (this.punVoiceNetwork.ClientState == Photon.Realtime.ClientState.PeerCreated
|| this.punVoiceNetwork.ClientState == Photon.Realtime.ClientState.Disconnected)
{
this.punVoiceNetwork.ConnectAndJoinRoom();
}
}
private void CalibrateButtonOnClick()
{
if (this.recorder && !this.recorder.VoiceDetectorCalibrating)
{
this.recorder.VoiceDetectorCalibrate(this.calibrationMilliSeconds);
}
}
private void Update()
{
// editor only two-ways binding for toggles
#if UNITY_EDITOR
this.InitToggles(this.globalSettings.GetComponentsInChildren<Toggle>());
#endif
if (this.recorder != null && this.recorder.LevelMeter != null)
{
this.voiceDebugText.text = string.Format("Amp: avg. {0:0.000000}, peak {1:0.000000}", this.recorder.LevelMeter.CurrentAvgAmp, this.recorder.LevelMeter.CurrentPeakAmp);
}
}
private void PunClientStateChanged(Photon.Realtime.ClientState fromState, Photon.Realtime.ClientState toState)
{
this.punState.text = string.Format("PUN: {0}", toState);
switch (toState)
{
case Photon.Realtime.ClientState.PeerCreated:
case Photon.Realtime.ClientState.Disconnected:
this.punSwitch.interactable = true;
this.punSwitchText.text = "PUN Connect";
break;
case Photon.Realtime.ClientState.Joined:
this.punSwitch.interactable = true;
this.punSwitchText.text = "PUN Disconnect";
break;
default:
this.punSwitch.interactable = false;
this.punSwitchText.text = "PUN busy";
break;
}
this.UpdateUiBasedOnVoiceState(this.punVoiceNetwork.ClientState);
}
private void VoiceClientStateChanged(Photon.Realtime.ClientState fromState, Photon.Realtime.ClientState toState)
{
this.UpdateUiBasedOnVoiceState(toState);
}
private void UpdateUiBasedOnVoiceState(Photon.Realtime.ClientState voiceClientState)
{
this.voiceState.text = string.Format("PhotonVoice: {0}", voiceClientState);
switch (voiceClientState)
{
case Photon.Realtime.ClientState.Joined:
this.voiceSwitch.interactable = true;
this.inGameSettings.SetActive(true);
this.voiceSwitchText.text = "Voice Disconnect";
this.InitToggles(this.inGameSettings.GetComponentsInChildren<Toggle>());
if (this.recorder != null)
{
this.calibrateButton.interactable = !this.recorder.VoiceDetectorCalibrating;
this.calibrateText.text = this.recorder.VoiceDetectorCalibrating ? "Calibrating" : string.Format("Calibrate ({0}s)", this.calibrationMilliSeconds / 1000);
}
else
{
this.calibrateButton.interactable = false;
this.calibrateText.text = "Unavailable";
}
break;
case Photon.Realtime.ClientState.PeerCreated:
case Photon.Realtime.ClientState.Disconnected:
if (PhotonNetwork.InRoom)
{
this.voiceSwitch.interactable = true;
this.voiceSwitchText.text = "Voice Connect";
this.voiceDebugText.text = String.Empty;
}
else
{
this.voiceSwitch.interactable = false;
this.voiceSwitchText.text = "Voice N/A";
this.voiceDebugText.text = String.Empty;
}
this.calibrateButton.interactable = false;
this.voiceSwitchText.text = "Voice Connect";
this.calibrateText.text = "Unavailable";
this.inGameSettings.SetActive(false);
break;
default:
this.voiceSwitch.interactable = false;
this.voiceSwitchText.text = "Voice busy";
break;
}
}
}
}