318 lines
8.9 KiB
C#
318 lines
8.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
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]
|
|
public int CurrentStep = 0;
|
|
|
|
[SerializeField]
|
|
public List<DialogueStepModel> DialogueSteps;
|
|
|
|
public void SetSpeakerName(string speakerName)
|
|
{
|
|
SpeakerName = speakerName;
|
|
|
|
DialogueSteps.ForEach(step => step.Header = speakerName);
|
|
}
|
|
|
|
#region finish action api
|
|
public void SetActionAfterEachDialogueStep(UnityEvent _endOfDialogueStepAction)
|
|
{
|
|
foreach(var dialogueStep in DialogueSteps)
|
|
{
|
|
dialogueStep.SetActionAfterDialogueStep(_endOfDialogueStepAction);
|
|
}
|
|
}
|
|
|
|
public void SetActionAfterEachDialogueStep(Action _finishDialogueAction)
|
|
{
|
|
foreach (var dialogueStep in DialogueSteps)
|
|
{
|
|
dialogueStep.SetActionAfterDialogueStep(_finishDialogueAction);
|
|
}
|
|
}
|
|
|
|
public void SetActionAfterDialogueStep(int dialogueStepNo, UnityEvent _endOfDialogueStepAction)
|
|
{
|
|
if(DialogueSteps.Count >= dialogueStepNo)
|
|
DialogueSteps[dialogueStepNo].SetActionAfterDialogueStep(_endOfDialogueStepAction);
|
|
}
|
|
public void SetActionAfterDialogueStep(int dialogueStepNo, Action _finishDialogueAction)
|
|
{
|
|
/* Debug.Log(dialogueStepNo); */
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Function to
|
|
/// - close panel
|
|
/// - INVOKE FINAL DIALOGUE ACTION
|
|
/// - mark as dispalyed
|
|
/// - increasing step number
|
|
///
|
|
/// Dont invoke final action!!!
|
|
/// </summary>
|
|
public void FinishDialogue()
|
|
{
|
|
foreach (var DialogueStep in DialogueSteps)
|
|
{
|
|
if (!DialogueStep.WasDisplayed)
|
|
{
|
|
// status must be changes before invoked final action - example - updating state
|
|
DialogueStep.WasDisplayed = true;
|
|
|
|
CurrentStep++;
|
|
|
|
DialogueStep.DialogueController.FinishCurrentDialogue(DialogueStep.DialogueController);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Function to
|
|
/// - close panel
|
|
/// - mark as dispalyed
|
|
/// - increasing step number
|
|
///
|
|
/// Dont invoke final action!!!
|
|
/// </summary>
|
|
public void CloseDialogue()
|
|
{
|
|
foreach (var DialogueStep in DialogueSteps)
|
|
{
|
|
if (!DialogueStep.WasDisplayed)
|
|
{
|
|
DialogueStep.WasDisplayed = true;
|
|
|
|
CurrentStep++;
|
|
|
|
DialogueStep.DialogueController.CloseCurrentPanel(DialogueStep.DialogueController);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 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) :)
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show next sentence ONLY in the same step
|
|
///
|
|
/// Return next panel status ponly for first faounded not displayed dialogue step
|
|
///
|
|
/// TODO change name this function and one below - but this break buttons with this action assigned
|
|
///
|
|
/// It would be much safer if function were return int not void bu unity event dont allow to bind methods in that scenario
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public void ShowNextPanel()
|
|
{
|
|
// we dont use foreach and "was displayed" condition because ther is DATA LEAK
|
|
// MISLEADING - last sentence mark step ad "wasDisplayed" but not increase "CurrentPanel" index
|
|
|
|
var currentStep = GetCurrentStep();
|
|
|
|
var nextSentenceIndex = currentStep.DialogueController.ShowNextPanel(currentStep.DialogueController);
|
|
|
|
if (!nextSentenceIndex)
|
|
{
|
|
CurrentStep++;
|
|
Debug.Log($"Increase - {CurrentStep}");
|
|
}
|
|
|
|
//return nextSentenceIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
public void GoToNextSentence()
|
|
{
|
|
// wskazujemy na inny krok kolejno niz nieoznaczony
|
|
// MISLEADING - last sentence mark step ad "wasDisplayed" but not increase "CurrentPanel" index
|
|
|
|
foreach (var DialogueStep in DialogueSteps)
|
|
{
|
|
if (!DialogueStep.WasDisplayed)
|
|
{
|
|
var nextSentence = DialogueStep.DialogueController.ShowNextPanel(DialogueStep.DialogueController);
|
|
|
|
if (!nextSentence)
|
|
{
|
|
DialogueStep.WasDisplayed = true;
|
|
|
|
CurrentStep++;
|
|
|
|
ShowDialogueStepPanel();
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
public void InvokeFinalAction()
|
|
{
|
|
foreach (var DialogueStep in DialogueSteps)
|
|
{
|
|
if (!DialogueStep.WasDisplayed)
|
|
{
|
|
DialogueStep.DialogueController.FinishDialoguStep();
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void BuildDialogue()
|
|
{
|
|
BuildDialogue(DialogueSteps);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Function to build each step of dialogue
|
|
/// </summary>
|
|
public void BuildDialogue(List<DialogueStepModel> Dialogue)
|
|
{
|
|
foreach (var dialogueStep in Dialogue)
|
|
{
|
|
dialogueStep.Header = SpeakerName;
|
|
|
|
dialogueStep.Build();
|
|
|
|
// synchronize current step counter
|
|
// cause ERROR - multi counting ....
|
|
}
|
|
}
|
|
|
|
#region Dialogue Status API
|
|
/// <summary>
|
|
/// Function to reset rememebered dialogue status
|
|
///
|
|
/// (Scriptable objects clones are overwritten during clone modification)
|
|
/// </summary>
|
|
public void ResetDialogue()
|
|
{
|
|
CurrentStep = 0;
|
|
|
|
DialogueSteps.ForEach(step => step.WasDisplayed = false);
|
|
}
|
|
|
|
public virtual void UpdateDialogueState(DialogueData dialogueData)
|
|
{
|
|
// 1 Rule - speaker name shouldnt change !!! its our 'key'
|
|
|
|
|
|
CurrentStep = dialogueData.CurrentStep;
|
|
|
|
for(int i=0; i < dialogueData.DialogueStepModelDataList.Count; i++)
|
|
{
|
|
DialogueSteps[i].WasDisplayed = dialogueData.DialogueStepModelDataList[i].WasDisplayed;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public DialogueStepModel? GetCurrentStep()
|
|
{// TODO - argument out of colection :/
|
|
|
|
var currentStep = DialogueSteps.ElementAtOrDefault(CurrentStep);
|
|
|
|
if (currentStep != null && currentStep.WasDisplayed && CurrentStep < DialogueSteps.Count)
|
|
CurrentStep++;
|
|
|
|
return DialogueSteps.Count > CurrentStep ? DialogueSteps[CurrentStep] : null;
|
|
}
|
|
|
|
|
|
|
|
/* public DialogueStepModel GetCurrentStep()
|
|
{
|
|
|
|
foreach (var DialogueStep in DialogueSteps)
|
|
{
|
|
Debug.Log("-" + DialogueStep.DialogueController.listOfDialogue.Count);
|
|
|
|
if (!DialogueStep.WasDisplayed && DialogueStep.DialogueController.listOfDialogue.Count != 0)
|
|
{
|
|
return DialogueStep;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}*/
|
|
}
|