using System; using System.Collections.Generic; using Convai.Scripts.Runtime.Core; using TMPro; using UnityEngine; namespace Convai.Scripts.Runtime.UI { /// /// This class is used to control the appearance settings of the UI. /// It requires a UIMicrophoneSettings, AudioSource, and MicrophoneInputChecker components to work. /// public class UIAppearanceSettings : MonoBehaviour { public static Action UIStatusChange; [Header("Settings Panel Animation Values")] [SerializeField] [Tooltip("Duration of the appearance preview animation.")] private float _appearancePreviewDuration = 1f; [Header("References")] [Tooltip("Dropdown for selecting the appearance.")] [SerializeField] private TMP_Dropdown _appearanceDropdown; /// /// FadeCanvas for handling appearance transitions. /// [SerializeField] private FadeCanvas _fadeCanvas; /// /// Duration for fade in animation. /// private readonly float _fadeInDuration = 0.3f; /// /// Duration for fade out animation. /// private readonly float _fadeOutDuration = 0.45f; /// /// Currently active appearance. /// private IChatUI _currentActiveAppearance; /// /// Reference to the UISettingsPanel for coordinating with appearance changes. /// private UISettingsPanel _uiSettingsPanel; /// /// Action notifying the change of appearance. /// public Action OnAppearanceChanged; /// /// Initialization when the script is loaded. /// private void Awake() { // Clear existing options in the dropdown. _appearanceDropdown.ClearOptions(); // Get reference to the UISettingsPanel. _uiSettingsPanel = GetComponent(); } private void Start() { InitializeAppearanceDropdown(); } /// /// Subscribe to events when this component is enabled. /// private void OnEnable() { // Subscribe to the event when saved data is loaded. UISaveLoadSystem.Instance.OnLoad += UISaveLoadSystem_OnLoad; // Subscribe to the event when data is saved. UISaveLoadSystem.Instance.OnSave += UISaveLoadSystem_OnSave; ConvaiNPCManager.Instance.OnActiveNPCChanged += ConvaiNPCManager_OnActiveNPCChanged; } /// /// Unsubscribe from events when this component is disabled. /// private void OnDisable() { // Unsubscribe from the event when saved data is loaded. UISaveLoadSystem.Instance.OnLoad -= UISaveLoadSystem_OnLoad; // Unsubscribe from the event when data is saved. UISaveLoadSystem.Instance.OnSave -= UISaveLoadSystem_OnSave; ConvaiNPCManager.Instance.OnActiveNPCChanged -= ConvaiNPCManager_OnActiveNPCChanged; } /// /// Initialize the appearance dropdown with available options. /// private void InitializeAppearanceDropdown() { List appearanceNames = new(); foreach (KeyValuePair appearance in ConvaiChatUIHandler.Instance .GetUIAppearances) appearanceNames.Add(appearance.Key.ToString()); _appearanceDropdown.AddOptions(appearanceNames); int value = (int)UISaveLoadSystem.Instance.UIType; _appearanceDropdown.value = value; // Subscribe to the appearance change event. _appearanceDropdown.onValueChanged.AddListener(ChangeAppearance); } /// /// Event handler for when the active NPC changes. /// private void ConvaiNPCManager_OnActiveNPCChanged(ConvaiNPC newActiveNPC) { if (newActiveNPC != null) { if (!UISaveLoadSystem.Instance.TranscriptUIActiveStatus) return; _fadeCanvas.StartFadeIn(_currentActiveAppearance.GetCanvasGroup(), _fadeInDuration); UIStatusChange?.Invoke(true); } else { _fadeCanvas.OnCurrentFadeCompleted += FadeOutChat; _fadeCanvas.StartFadeOut(_currentActiveAppearance.GetCanvasGroup(), _fadeOutDuration); } } private void FadeOutChat() { UIStatusChange?.Invoke(false); _fadeCanvas.OnCurrentFadeCompleted -= FadeOutChat; } /// /// Event handler when saved data is loaded. /// private void UISaveLoadSystem_OnLoad() { // Set the current active appearance based on loaded data. _currentActiveAppearance = ConvaiChatUIHandler.Instance.GetCurrentUI(); } /// /// Event handler when data is saved. /// private void UISaveLoadSystem_OnSave() { } /// /// Event handler for appearance change. /// private void ChangeAppearance(int selectedOptionNumber) { // Initiate Settings Panel transition. _uiSettingsPanel.FadeOutFadeinWithGap(_fadeInDuration, _fadeOutDuration, _appearancePreviewDuration); // Deactivate the current appearance. _currentActiveAppearance.DeactivateUI(); ConvaiChatUIHandler.UIType newUIType = (ConvaiChatUIHandler.UIType)_appearanceDropdown.value; ConvaiChatUIHandler.Instance.SetUIType(newUIType); _currentActiveAppearance = ConvaiChatUIHandler.Instance.GetChatUIByUIType(newUIType); // Update the current active appearance reference. _currentActiveAppearance.ActivateUI(); // Initiate appearance transition. FadeInFadeOutWithGap(); OnAppearanceChanged?.Invoke(); } /// /// Fade out the currently active appearance. /// public void FadeOutCurrentAppearance() { _fadeCanvas.StartFadeOut(_currentActiveAppearance.GetCanvasGroup(), _fadeOutDuration); } /// /// Fade in the currently active appearance. /// public void FadeInCurrentAppearance() { _fadeCanvas.StartFadeIn(_currentActiveAppearance.GetCanvasGroup(), _fadeInDuration); } /// /// Perform a fade-in, fade-out transition with a gap in between. /// private void FadeInFadeOutWithGap() { _fadeCanvas.StartFadeInFadeOutWithGap(_currentActiveAppearance.GetCanvasGroup(), _fadeInDuration, _fadeOutDuration, _appearancePreviewDuration); } /// /// Get the currently active appearance. /// public IChatUI GetCurrentActiveAppearance() { return _currentActiveAppearance; } } }