diff --git a/Assets/Editor/Dialogue/DialogueGraphImporter.cs b/Assets/Editor/Dialogue/DialogueGraphImporter.cs index 3ca70124..28f95c01 100644 --- a/Assets/Editor/Dialogue/DialogueGraphImporter.cs +++ b/Assets/Editor/Dialogue/DialogueGraphImporter.cs @@ -48,6 +48,9 @@ namespace Editor.Dialogue // Process node based on its type if (iNode is DialogueNode dialogueNode) { + // Process base dialogue node properties (for all node types) + ProcessDialogueNodeBase(dialogueNode, runtimeNode); + if (iNode is WaitOnPuzzleStep puzzleNode) { ProcessPuzzleNode(puzzleNode, runtimeNode); @@ -60,9 +63,6 @@ namespace Editor.Dialogue { ProcessSlotNode(slotNode, runtimeNode); } - - // Process base dialogue node properties (for all node types) - ProcessDialogueNodeBase(dialogueNode, runtimeNode); } else if (iNode is EndNode) { diff --git a/Assets/Scripts/Dialogue/DialogueComponent.cs b/Assets/Scripts/Dialogue/DialogueComponent.cs index cafc92aa..f484b58b 100644 --- a/Assets/Scripts/Dialogue/DialogueComponent.cs +++ b/Assets/Scripts/Dialogue/DialogueComponent.cs @@ -46,7 +46,7 @@ namespace Dialogue } // Auto-start the dialogue - StartDialogue(); + // StartDialogue(); var interactable = GetComponent(); if (interactable != null) @@ -54,15 +54,26 @@ namespace Dialogue interactable.characterArrived.AddListener(OnCharacterArrived); } - if (HasAnyLines()) + // Update bubble visibility based on whether we have lines + if (speechBubble != null) { - speechBubble.SetText(". . ."); + speechBubble.UpdatePromptVisibility(HasAnyLines()); } } private void OnCharacterArrived() { - speechBubble.SetText(GetCurrentDialogueLine()); + if (speechBubble == null || ! HasAnyLines()) return; + + AdvanceDialogueState(); + + // Get the current dialogue line + string line = GetCurrentDialogueLine(); + + // Display the line with the new method that handles timed updates + speechBubble.DisplayDialogueLine(line, HasAnyLines()); + + // Advance dialogue state for next interaction } private void OnDestroy() @@ -100,6 +111,12 @@ namespace Dialogue // Process the node ProcessCurrentNode(); + + // Update bubble visibility based on whether we have lines + if (speechBubble != null) + { + speechBubble.UpdatePromptVisibility(HasAnyLines()); + } } /// @@ -124,9 +141,6 @@ namespace Dialogue currentLine = currentNode.dialogueLines[currentLineIndex]; } - // Advance dialogue state for next interaction - AdvanceDialogueState(); - // Return the current line return currentLine; } @@ -138,11 +152,7 @@ namespace Dialogue { if (!IsActive || IsCompleted || currentNode == null) return; - - // If we're on a conditional node, we can't advance past it until condition is met - if (IsWaitingForCondition()) - return; - + // If we have more lines in the current node, advance to the next line if (currentLineIndex < currentNode.dialogueLines.Count - 1) { @@ -157,8 +167,19 @@ namespace Dialogue return; } - // Otherwise, move to the next node - MoveToNextNode(); + // If we're at a node that doesn't have a next node, we're done + if (string.IsNullOrEmpty(currentNode.nextNodeID)) + { + IsActive = false; + IsCompleted = true; + return; + } + + // Move to the next node only if no conditions to wait for + if (!IsWaitingForCondition()) + { + MoveToNextNode(); + } } private void MoveToNextNode() @@ -246,7 +267,16 @@ namespace Dialogue { // Move to next node automatically when condition is met MoveToNextNode(); - OnDialogueChanged?.Invoke(GetCurrentDialogueLine()); + + // Notify any listeners about the dialogue change + string line = GetCurrentDialogueLine(); + OnDialogueChanged?.Invoke(line); + + // Update bubble visibility after state change + if (speechBubble != null) + { + speechBubble.UpdatePromptVisibility(HasAnyLines()); + } } } @@ -262,7 +292,22 @@ namespace Dialogue { // Move to next node automatically when condition is met MoveToNextNode(); - OnDialogueChanged?.Invoke(GetCurrentDialogueLine()); + + // Notify any listeners about the dialogue change + string line = GetCurrentDialogueLine(); + OnDialogueChanged?.Invoke(line); + + // Update bubble visibility after state change + if (speechBubble != null) + { + speechBubble.UpdatePromptVisibility(HasAnyLines()); + } + } + + // Always check if any dialogue was unblocked by this pickup + if (speechBubble != null) + { + speechBubble.UpdatePromptVisibility(HasAnyLines()); } } @@ -278,7 +323,22 @@ namespace Dialogue { // Move to next node automatically when condition is met MoveToNextNode(); - OnDialogueChanged?.Invoke(GetCurrentDialogueLine()); + + // Notify any listeners about the dialogue change + string line = GetCurrentDialogueLine(); + OnDialogueChanged?.Invoke(line); + + // Update bubble visibility after state change + if (speechBubble != null) + { + speechBubble.UpdatePromptVisibility(HasAnyLines()); + } + } + + // Always check if any dialogue was unblocked by this slotting + if (speechBubble != null) + { + speechBubble.UpdatePromptVisibility(HasAnyLines()); } } @@ -373,10 +433,10 @@ namespace Dialogue } // Special case for conditional nodes waiting on conditions - if (IsWaitingForCondition()) - { - return currentNode.dialogueLines.Count > 0; - } + // if (IsWaitingForCondition()) + // { + // return currentNode.dialogueLines.Count > 0; + // } return false; } diff --git a/Assets/Scripts/Dialogue/SpeechBubble.cs b/Assets/Scripts/Dialogue/SpeechBubble.cs index 4848e952..886e802a 100644 --- a/Assets/Scripts/Dialogue/SpeechBubble.cs +++ b/Assets/Scripts/Dialogue/SpeechBubble.cs @@ -23,8 +23,11 @@ namespace Dialogue [SerializeField] private AudioSource typingSoundSource; [SerializeField] private float typingSoundFrequency = 3; // Play sound every X characters [SerializeField] private bool useRichText = true; // Whether to respect rich text tags + [SerializeField] private float dialogueDisplayTime = 1.5f; // Time in seconds to display dialogue before showing prompt + [SerializeField] private string dialoguePromptText = ". . ."; // Text to show as a prompt for available dialogue private Coroutine typewriterCoroutine; + private Coroutine promptUpdateCoroutine; private string currentFullText = string.Empty; private bool isVisible = false; @@ -56,6 +59,13 @@ namespace Dialogue StopCoroutine(typewriterCoroutine); typewriterCoroutine = null; } + + // Stop any prompt update coroutine + if (promptUpdateCoroutine != null) + { + StopCoroutine(promptUpdateCoroutine); + promptUpdateCoroutine = null; + } } /// @@ -105,6 +115,66 @@ namespace Dialogue if (!isVisible) Show(); } + + /// + /// Display a dialogue line and handle prompt visibility afterward + /// + /// The dialogue line to display + /// Whether there are more dialogue lines available + public void DisplayDialogueLine(string line, bool hasMoreDialogue) + { + // Cancel any existing prompt update + if (promptUpdateCoroutine != null) + { + StopCoroutine(promptUpdateCoroutine); + promptUpdateCoroutine = null; + } + + // Display the dialogue line + if (!string.IsNullOrEmpty(line)) + { + SetText(line); + + // After a delay, update the prompt visibility + promptUpdateCoroutine = StartCoroutine(UpdatePromptAfterDelay(hasMoreDialogue)); + } + else + { + // If no line to display, update prompt visibility immediately + UpdatePromptVisibility(hasMoreDialogue); + } + } + + /// + /// Update the speech bubble to either show a prompt or hide based on dialogue availability + /// + /// Whether dialogue is available + public void UpdatePromptVisibility(bool hasDialogueAvailable) + { + if (hasDialogueAvailable) + { + Show(); + SetText(dialoguePromptText); + } + else + { + Hide(); + } + } + + /// + /// Coroutine to update the prompt visibility after a delay + /// + private IEnumerator UpdatePromptAfterDelay(bool hasMoreDialogue) + { + // Wait for the configured display time + yield return new WaitForSeconds(dialogueDisplayTime); + + // Update the prompt visibility + UpdatePromptVisibility(hasMoreDialogue); + + promptUpdateCoroutine = null; + } /// /// Change the display mode diff --git a/Assets/Scripts/Dialogue/SpeechBubbleController.cs b/Assets/Scripts/Dialogue/SpeechBubbleController.cs new file mode 100644 index 00000000..e02abfc9 --- /dev/null +++ b/Assets/Scripts/Dialogue/SpeechBubbleController.cs @@ -0,0 +1 @@ + diff --git a/Assets/Scripts/Dialogue/SpeechBubbleController.cs.meta b/Assets/Scripts/Dialogue/SpeechBubbleController.cs.meta new file mode 100644 index 00000000..fdd11866 --- /dev/null +++ b/Assets/Scripts/Dialogue/SpeechBubbleController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 877344c7a0014922bc3a2a469e03792d +timeCreated: 1759050622 \ No newline at end of file