using System; using System.Collections.Generic; using System.Linq; using UnityEngine; [Serializable] [CreateAssetMenu(fileName = "New Dialogue", menuName = "Dialogue/New Dialogue")] public class Dialogue : ScriptableObject { [SerializeField] int CurrentDialogue = 0; [SerializeField] public List>> MultiWayDialogue; /* Dialogues - list of dialoges Steps bucket (one dialogue unit) - list of liner 'steps', finished special action, whole can be stopped special requirements (like go and do something - to declared in 'finish action') Steps - its a cell package contains 'sentences' (one per panel) Sentence - its a opanel with phrase and buttons */ /* * WAZNE: * Jesli przechodzimy odpowiedzia do nastepnego dialogu musi to byc osttani panel w obecnym!!! */ public void Start() { /* CODE DIALOGUE DECLARATION EXAMPLE DialogueController DialogueStep = new DialogueController(); DialogueStep.AddSentence(new DialogueModel("lorem ipsum")); *//* di.AddSentence(new QuestionDialogueModel("tolore dolore?", new List> { new Tuple("AcceptButton", CustomPanel), new Tuple("RejectButton", QuestionPanel) }));*//* DialogueStep.SetActionAfterDialogueEnds(() => { }); DialogueStepModel dialogueStepModel = new DialogueStepModel(DialogueStep); DialogueStepsList = new List { dialogueStepModel }; */ /*if (MultiWayDialogue.Count > 0) BuildDialogue(MultiWayDialogue.Where(el => el.Key == CurrentDialogue).First().Value);*/ } public void StartDialogue() { // 1. Build BuildDialogue(MultiWayDialogue.Where(el => el.Key == CurrentDialogue).First().Value); // 2. Show first step ShowStep(); } public void BreakDialogue() { // 1. Find first yet undisplayed for player anbd show var dialogueStepsList = MultiWayDialogue.Where(el => el.Key == CurrentDialogue).ToArray().First().Value; foreach (var DialogueStep in dialogueStepsList) { Debug.Log($"List of dialogue count: {DialogueStep.DialogueController.listOfDialogue.Count}"); if (!DialogueStep.WasDisplayed && DialogueStep.DialogueController.listOfDialogue.Count != 0) { Debug.Log("Break Dialogue - close panel"); DialogueStep.DialogueController.CloseCurrentPanel(); // close panel break; } Debug.Log("a"); } } /// /// 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 ShowStep() { // 1. Find first yet undisplayed for player anbd show var dialogueStepsList = MultiWayDialogue.Where(el => el.Key == CurrentDialogue).ToArray().First().Value; foreach (var DialogueStep in dialogueStepsList) { if (!DialogueStep.WasDisplayed && DialogueStep.DialogueController.listOfDialogue.Count != 0) { DialogueStep.DialogueController.Show(DialogueStep.DialogueController.listOfDialogue.Dequeue()); // create panel break; } } } /// /// Dialogue API /// /// 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() { // 1. Find first yet undisplayed for player anbd show var dialogueStepsList = MultiWayDialogue.Where(el => el.Key == CurrentDialogue).ToArray().First().Value; foreach (var DialogueStep in dialogueStepsList) { if (!DialogueStep.WasDisplayed) { var nextSentence = DialogueStep.DialogueController.ShowNextPanel(DialogueStep.DialogueController); if (!nextSentence) { DialogueStep.WasDisplayed = true; ShowStep(); } break; } } } /// /// Dialogue API /// /// Function to prepare next dialogue to start after one more palyer interaction with actor /// - ends current dialogue (destroy panel & invoke finish action - if setupped) /// - set new dialogue pointer /// /// /// public void SetNextDialogue(int dialogueNumber) { if (MultiWayDialogue.Where(el => el.Key == dialogueNumber).ToArray().Count() == 0) return; // 1. Make sure to close current panel after finishing current dialogue and 'finish action' will invoked if setuped GoToNextSentence(); // 2. Chane index CurrentDialogue = dialogueNumber; } /// /// Dialogue API /// /// Function to finish current dialog and immediately start next one /// /// /// public void GoToNextDialogue(int dialogueNumber) { // 1. Prepare necessary environoment parts SetNextDialogue(dialogueNumber); // 3. Build new dialogue BuildDialogue(MultiWayDialogue.Where(el => el.Key == CurrentDialogue).First().Value); // 4. Start new dialogue bucket ShowStep(); } /// /// Build each step of dialogue /// private void BuildDialogue(List Dialogue) { foreach (var dialogueStep in Dialogue) { dialogueStep.Build(); } } public (int, int) DialogueStepStatus() { var currentDialogueStepIndex = MultiWayDialogue .Where(el => el.Key == CurrentDialogue) .Select(el => el.Value) .First() .Where(step => step.WasDisplayed == true) .ToArray() .Count() ; return(CurrentDialogue, currentDialogueStepIndex); } }