using System; using Nullframes.Intrigues.Utils; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; namespace Nullframes.Intrigues.UI { public class DialogueManager : IIEditor { private static DialogueManager instance; public static DialogueManager Instance { get { if (instance != null) return instance; _ = IM.DialogueManager ?? throw new ArgumentException(STATIC.DEBUG_DIALOGUE_MANAGER_NOT_FOUND); var dialogueManager = Instantiate(IM.DialogueManager.gameObject, IM.Transform) .GetComponent(); instance = dialogueManager; return instance; } } private void Awake() { SceneManager.activeSceneChanged += (_, _) => { // if (CloseWhenActiveSceneChanged) { foreach (var panel in Instance.GetComponentsInChildren(true)) { // if (panel.Dialogue is { IsSchemeDialog: true }) continue; panel.Dialogue?.Close(true); } // } }; } /// /// Determines whether the most recently opened dialogue should be displayed on top. /// /// /// When set to true, this property ensures that the latest opened dialogue is always displayed at the top of the stack, /// making it the most visible or prioritized dialogue. This is useful in scenarios where multiple dialogues are opened /// and the most recent one needs immediate attention or interaction. /// public bool LastOnTop; // public bool CloseWhenActiveSceneChanged; public bool unscaledTime; public Color conditionalChoiceColor = new (0.4980392156862745f, 0.6235294117647059f, 0.8588235294117647f); public Color disabledChoiceColor = new (0.8196078431372549f, 0.35294117647058826f, 0.2823529411764706f); public Color CircleKeywordColor = new (0.8196078431372549f, 0.8392156862745098f, 0.47058823529411764f); public Color SquareKeywordColor = new (0.8392156862745098f, 0.5568627450980392f, 0.3843137254901961f); public Color LinkColor = new (0.5568627450980392f, 0.8117647058823529f, 0.4235294117647059f); public DialoguePanel dialoguePanel; [Space(10)] public UnityEvent onDialogueOpen; // Event triggered when a dialogue is opened. public UnityEvent onDialogueClose; // Event triggered when a dialogue is closed. public UnityEvent onDialogueShow; // Event triggered when a dialogue is shows. public UnityEvent onDialogueHide; // Event triggered when a dialogue is hides. public Action onDialogueClose_Ignore; /// /// Opens a dialogue with the specified title and content. /// /// The title of the dialogue. /// The content of the dialogue. /// The duration of the dialog window. The window closes when the time is up. /// This indicates whether the dialog is included in a node flow or not. /// If true, the Typewriter effect is applied. /// . /// The opened dialogue. public static Dialogue OpenDialogue(string title, string content, float time = 0, bool typeWriter = false, Action onUpdate = null, bool isSchemeDialog = false) { // Create a new instance of the dialogue panel by duplicating the original dialogue panel. var _dialoguePanel = Instance.dialoguePanel.gameObject.Duplicate(); content = content.Replace("", ""); // Set up the duplicated dialogue panel with the specified title and content. _dialoguePanel.Setup(title, content); // Create a new dialogue instance using the duplicated dialogue panel. var dialogue = new Dialogue(_dialoguePanel, isSchemeDialog); dialogue.Init(time, typeWriter, onUpdate); // Activate the game object of the duplicated dialogue panel. _dialoguePanel.gameObject.SetActive(true); // Trigger the onDialogueOpen event of the DialogueManager instance. Instance.onDialogueOpen.Invoke(dialogue); _dialoguePanel.Dialogue = dialogue; // Return the opened dialogue. return dialogue; } /// /// Closes the dialogue windows. /// /// If true, only scheme dialogue windows are closed. If false, all dialogue windows are closed. /// If true, closes the dialogues without sending notifications. /// /// This method iterates through all DialoguePanel instances and closes them. If 'justSchemeDialog' is true, /// it only closes those that are marked as scheme dialogs. The 'withoutNotification' parameter determines /// whether to close the dialogues silently without triggering additional notifications. /// public static void Close(bool justSchemeDialog = false, bool withoutNotification = false) { if (Instance == null) return; foreach (var panel in Instance.GetComponentsInChildren(true)) { if (justSchemeDialog && panel.Dialogue is { IsSchemeDialog: false }) continue; panel.Dialogue?.Close(withoutNotification); } } /// /// Shows hidden dialogue windows. /// /// If true, only shows scheme dialogue windows. If false, shows all dialogue windows. /// If true, hides the dialogues without sending notifications. /// /// This method goes through all DialoguePanel instances and makes them visible. If 'justSchemeDialog' is true, /// only the dialogue windows marked as scheme dialogs are made visible. /// public static void HideAll(bool justSchemeDialog = false, bool withoutNotification = false) { if (Instance == null) return; foreach (var panel in Instance.GetComponentsInChildren(true)) { if (justSchemeDialog && panel.Dialogue is { IsSchemeDialog: false }) continue; panel.Dialogue?.Hide(withoutNotification); } } /// /// Hides the dialogue windows. /// /// If true, only hides scheme dialogue windows. If false, hides all dialogue windows. /// If true, shows the dialogues without sending notifications. /// /// This method iterates through each DialoguePanel instance and hides them. If 'justSchemeDialog' is set to true, /// it only hides those dialogues that are identified as scheme dialogs. /// public static void ShowAll(bool justSchemeDialog = false, bool withoutNotification = false) { if (Instance == null) return; foreach (var panel in Instance.GetComponentsInChildren(true)) { if (justSchemeDialog && panel.Dialogue is { IsSchemeDialog: false }) continue; panel.Dialogue?.Show(withoutNotification); } } } }