using System; using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.Events; [Serializable] [CreateAssetMenu(fileName = "New Dialogue", menuName = "Dialogue/New Dialogue")] public class Dialogue : ScriptableObject, IDialogue { [SerializeField] public string SpeakerName; [SerializeField] int CurrentStep = 0; [SerializeField] public List DialogueSteps; public void SetSpeakerName(string speakerName) { SpeakerName = speakerName; DialogueSteps.ForEach(step => step.Header = speakerName); } #region finish action api public void SetActionAfterDialogueStep(int dialogueStepNo, UnityEvent _endOfDialogueStepAction) { if(DialogueSteps.Count >= dialogueStepNo) DialogueSteps[dialogueStepNo].SetActionAfterDialogueStep(_endOfDialogueStepAction); } public void SetActionAfterDialogueStep(int dialogueStepNo, Action _finishDialogueAction) { if (DialogueSteps.Count >= dialogueStepNo) DialogueSteps[dialogueStepNo].SetActionAfterDialogueStep(_finishDialogueAction); } #endregion #region dialogue displaying api public void StartDialogue() { // 1. Build BuildDialogue(DialogueSteps); // 2. Show first step ShowDialogueStepPanel(); } public void BreakDialogueStep() { foreach (var DialogueStep in DialogueSteps) { if (!DialogueStep.WasDisplayed && DialogueStep.DialogueController.CurrentPanel != null) { DialogueStep.DialogueController.CloseCurrentPanel(); // close panel break; } } } /// /// Dialogue API /// /// MAIN bunction to begin dialogue /// Create new panel instance on scene by force with sentence from queue /// /// The best way is to invoked its after player reaction from other script (by event - collision) :) /// public void ShowDialogueStepPanel() { foreach (var DialogueStep in DialogueSteps) { if (!DialogueStep.WasDisplayed && DialogueStep.DialogueController.listOfDialogue.Count != 0) { DialogueStep.DialogueController.Show(DialogueStep.DialogueController.listOfDialogue.Dequeue()); // create panel break; } } } /// /// Dialogue API /// /// Function to automaticly go to next dialgue sentence (in this or next step eg after pressing button on panel /// It provide that dialogue not braking after finishing current step /// /// The dialogue follows the order of the lists ! ! /// /// It's default function to get next sentence if dialogue is currently started /// It is responsible for detecting /// 1) if there is any dialogue panel already created before displaying next sentence /// 2) if its last panel sentence and invoiking 'end dialogue' action /// /// Whats more, if there was no more sentences in 'step', althroughr closing panel go to next step automatiiccally /// public void GoToNextSentence() { foreach (var DialogueStep in DialogueSteps) { if (!DialogueStep.WasDisplayed) { var nextSentence = DialogueStep.DialogueController.ShowNextPanel(DialogueStep.DialogueController); if (!nextSentence) { DialogueStep.WasDisplayed = true; ShowDialogueStepPanel(); } break; } } } #endregion /// /// Function to build each step of dialogue /// public void BuildDialogue(List Dialogue) { foreach (var dialogueStep in Dialogue) { dialogueStep.Header = SpeakerName; dialogueStep.Build(); } } /// /// Function to reset rememebered dialogue status /// /// (Scriptable objects clones are overwritten during clone modification) /// public void ResetDialogue() { DialogueSteps.ForEach(step => step.WasDisplayed = false); } }