using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.Android; using UnityEngine.UI; /// /// This class is used to manage the microphone settings in the UI. /// namespace Convai.Scripts.Utils { public class UIMicrophoneSettings : MonoBehaviour { [Tooltip("Dropdown to select the microphone device to use.")] [SerializeField] private TMP_Dropdown _microphoneSelectDropdown; [Tooltip("Button to control the recording.")] [SerializeField] private Button _recordControllerButton; [Tooltip("Text to display the status of the recording system.")] [SerializeField] private TextMeshProUGUI _recordSystemStatusText; /// /// Image component of the recording control button. /// private Image _buttonImage; /// /// Text component of the recording control button. /// private TextMeshProUGUI _buttonText; /// /// Reference to the MicrophoneManager to subscribe to its events. /// private MicrophoneTestController _microphoneTestController; /// /// Index of the selected microphone device. /// private int _selectedMicrophoneDeviceNumber; /// /// Initialize references. /// private void Awake() { _microphoneTestController = GetComponent(); _buttonImage = _recordControllerButton.GetComponent(); _buttonText = _recordControllerButton.GetComponentInChildren(); RequestMicrophonePermissions(); } /// /// Request Microphone permissions on Android or iOS. /// private void RequestMicrophonePermissions() { #if UNITY_ANDROID if (Permission.HasUserAuthorizedPermission(Permission.Microphone)) { // Initialize Microphone devices if permission is already granted. InitializeMicrophoneDevices(); } else { // Request Microphone permission with callback var callbacks = new PermissionCallbacks(); callbacks.PermissionGranted += PermissionCallbacks_PermissionGranted; callbacks.PermissionDenied += s => ShowNoMicrophoneDetectedNotification(); callbacks.PermissionDeniedAndDontAskAgain += s => ShowNoMicrophoneDetectedNotification(); Permission.RequestUserPermission(Permission.Microphone, callbacks); } #elif UNITY_IOS // Check Microphone permission on iOS and start coroutine to request permission if not granted. StartCoroutine(iOSTryToAccessMicrophone()); #endif } /// /// Show notification when no microphone is detected. /// private void ShowNoMicrophoneDetectedNotification() { NotificationSystemHandler.Instance.NotificationRequest(NotificationType.NoMicrophoneDetected); _recordSystemStatusText.text = "No Microphone Detected..."; } /// /// Subscribe to events when this component is enabled. /// private void OnEnable() { _microphoneTestController.OnRecordStarted += MicrophoneTestControllerOnRecordStarted; _microphoneTestController.OnRecordCompleted += MicrophoneTestControllerOnRecordCompleted; _microphoneTestController.OnAudioClipCompleted += MicrophoneTestControllerOnAudioClipCompleted; UISaveLoadSystem.Instance.OnLoad += UISaveLoadSystem_OnLoad; UISaveLoadSystem.Instance.OnSave += UISaveLoadSystem_OnSave; #if !UNITY_ANDROID && !UNITY_IOS InitializeMicrophoneDevices(); #endif } /// /// Unsubscribe from events when this component is disabled. /// private void OnDisable() { _microphoneTestController.OnRecordStarted -= MicrophoneTestControllerOnRecordStarted; _microphoneTestController.OnRecordCompleted -= MicrophoneTestControllerOnRecordCompleted; _microphoneTestController.OnAudioClipCompleted -= MicrophoneTestControllerOnAudioClipCompleted; UISaveLoadSystem.Instance.OnLoad -= UISaveLoadSystem_OnLoad; UISaveLoadSystem.Instance.OnSave -= UISaveLoadSystem_OnSave; } /// /// Initialize the dropdown with available microphone devices after obtaining permission. /// private void InitializeMicrophoneDevices() { _microphoneSelectDropdown.ClearOptions(); _microphoneSelectDropdown.AddOptions(new List(Microphone.devices)); _microphoneSelectDropdown.onValueChanged.AddListener(ChangeSelectedDevice); _recordSystemStatusText.text = "Waiting For Record..."; // Checking if system has at-least one microphone to record the audio if (!MicrophoneManager.Instance.HasAnyMicrophoneDevices()) { ShowNoMicrophoneDetectedNotification(); } } /// /// Coroutine to check and request Microphone permission on iOS. /// private IEnumerator iOSTryToAccessMicrophone() { if (Application.HasUserAuthorization(UserAuthorization.Microphone)) { InitializeMicrophoneDevices(); } else { yield return Application.RequestUserAuthorization(UserAuthorization.Microphone); if (Application.HasUserAuthorization(UserAuthorization.Microphone)) { InitializeMicrophoneDevices(); } else { ShowNoMicrophoneDetectedNotification(); } } } /// /// Callback when Microphone permission is granted on Android. /// /// Permission string private void PermissionCallbacks_PermissionGranted(string obj) { InitializeMicrophoneDevices(); Debug.Log("Permission Granted!!!"); } /// /// Event handler when the selected microphone device is changed. /// private void ChangeSelectedDevice(int selectedDeviceNumber) { _selectedMicrophoneDeviceNumber = selectedDeviceNumber; MicrophoneManager.Instance.SetSelectedMicrophoneIndex(selectedDeviceNumber); UISaveLoadSystem.Instance.SelectedMicrophoneDeviceNumber = _selectedMicrophoneDeviceNumber; Logger.Info("Microphone Device Updated.", Logger.LogCategory.Character); } /// /// Event handler when saved data is loaded. /// private void UISaveLoadSystem_OnLoad() { _microphoneSelectDropdown.value = UISaveLoadSystem.Instance.SelectedMicrophoneDeviceNumber; Logger.Info("Loaded Microphone Device. ", Logger.LogCategory.Character); } /// /// Event handler when data is saved. /// private void UISaveLoadSystem_OnSave() { UISaveLoadSystem.Instance.SelectedMicrophoneDeviceNumber = _microphoneSelectDropdown.value; } /// /// Event handler when a recording is started. /// private void MicrophoneTestControllerOnRecordStarted() { _recordSystemStatusText.text = "Recording..."; _buttonImage.color = Color.red; _buttonText.text = "Stop"; _buttonText.color = new Color(1, 1, 1); } /// /// Event handler when a recording is completed. /// private void MicrophoneTestControllerOnRecordCompleted() { _recordSystemStatusText.text = "Playing..."; _buttonImage.color = Color.green; _buttonText.text = "Rec"; _buttonText.color = new Color(0.14f, 0.14f, 0.14f); } /// /// Event handler when the audio clip playback is completed. /// private void MicrophoneTestControllerOnAudioClipCompleted() { _recordSystemStatusText.text = "Waiting For Record..."; } /// /// Returns the microphone selection dropdown object. /// public TMP_Dropdown GetMicrophoneSelectDropdown() { return _microphoneSelectDropdown; } /// /// Returns the record control button object. /// public Button GetRecordControllerButton() { return _recordControllerButton; } /// /// Returns the selected microphone device name. /// public string GetSelectedMicrophoneDeviceName() { if (_selectedMicrophoneDeviceNumber < 0 || _selectedMicrophoneDeviceNumber >= _microphoneSelectDropdown.options.Count) return string.Empty; return _microphoneSelectDropdown.options[_selectedMicrophoneDeviceNumber].text; } } }