using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; using UnityEngine.Events; [RequireComponent(typeof(NPC))] public class DialogueManager : MonoBehaviour { [SerializeField] public string SpeakerName; [SerializeField] public LanguageDetector languageDetector; /* We user object CLONED TO PREVENT overwritting changes in main object inassets */ [SerializeField] public MultiDialogue Dialogue; // List, Value : UnityEvent> public List, UnityEvent>> EndactionEventList; [SerializeField] public KeyCode keyToOpen = KeyCode.E; public bool CanBeOpened = true; /// /// This flag tell that manager will open dialogue automatically after /// - beeing in collision range /// - when dialogue is closed /// - when Player press KeyToOpen button /// /// Change var status in other sctipt if you want to use other triggers to open dialogue /// public bool OpenInDefaultWay = true; public virtual void Start() { // create and config dailogue CreateInstanceBasedOnLanguage(); Dialogue.BuildCurrentDialogue(); /* Debug.Log(Dialogue.DialogueStepStatus()); Debug.Log(Dialogue .Dialogues .Where(dialogue => dialogue.Key == Dialogue.DialogueStepStatus().Item1) .First() .Value); Debug.Log( Dialogue .Dialogues .Where(dialogue => dialogue.Key == Dialogue.DialogueStepStatus().Item1) .First() .Value .DialogueSteps.Count()); Debug.Log( Dialogue .Dialogues .Where(dialogue => dialogue.Key == Dialogue.DialogueStepStatus().Item1) .First() .Value .DialogueSteps .ElementAtOrDefault(Dialogue.DialogueStepStatus().Item2) ); Debug.Log( Dialogue .Dialogues .Where(dialogue => dialogue.Key == Dialogue.DialogueStepStatus().Item1) .First() .Value .DialogueSteps .ElementAtOrDefault(Dialogue.DialogueStepStatus().Item2) .DialogueController ); Debug.Log( Dialogue .Dialogues .Where(dialogue => dialogue.Key == Dialogue.DialogueStepStatus().Item1) .First() .Value .DialogueSteps .ElementAtOrDefault(Dialogue.DialogueStepStatus().Item2) .DialogueController .listOfDialogue.Count() ); Debug.Log(GetCurrentDialoguePanelStatus()); */ } public void Update() { if (OpenInDefaultWay && Input.GetKeyDown(keyToOpen) && OpenPanelCondition()) { OpenDialoguePanel(); } } public virtual void OnTriggerEnter2D(Collider2D collision) { // don't listen when component is disabled if (ComponentEnabledCondition()) return; if (collision.gameObject.tag == "Player") { CanBeOpened = true; SpeakerName = collision.gameObject.name; } } public virtual void OnTriggerExit2D(Collider2D collision) { // don't listen when component is disabled if (ComponentEnabledCondition() || !OpenInDefaultWay) return; if (collision.gameObject.tag == "Player") { CanBeOpened = false; if (GetCurrentDialoguePanelStatus()) { Dialogue.BreakDialogueStep(); } } } public virtual void CreateInstanceBasedOnLanguage() { Dialogue = Instantiate(languageDetector.DetectInstanceBasedOnLanguage()); // Bind setted actions BindEndActionsToDialogues(); // Add one more action Dialogue.Dialogues.ForEach(dial => dial.Value.SetActionAfterDialogueStep(dial.Key, dial.Value.ResetDialogue)); // reset dial } #region Open Panel API public void OpenDialoguePanel() { if(OpenPanelCondition()) { // Update speaker name before every opening Dialogue.SetSpeakerName(SpeakerName); gameObject.GetComponent().Dialogue.StartDialogue(); } } public virtual bool OpenPanelCondition() { /* * Conditions: * - player is in collision range * - panel assigned to next sentence in dialogue must be closed */ return IsInRangeCondition() && !GetCurrentDialoguePanelStatus(); } public bool IsInRangeCondition() { return CanBeOpened; } protected virtual bool ComponentEnabledCondition() { return !gameObject.GetComponent().enabled; } #endregion /// /// Opened = 1 /// Closed = 0 /// /// public virtual bool GetCurrentDialoguePanelStatus() { Debug.Log(Dialogue); var multiDialStatius = Dialogue.DialogueStepStatus(); Debug.Log(multiDialStatius); Debug.Log(Dialogue .Dialogues .Where(dialogue => dialogue.Key == multiDialStatius.Item1) .First() .Value .DialogueSteps); return Dialogue .Dialogues .Where(dialogue => dialogue.Key == multiDialStatius.Item1) .First() .Value .DialogueSteps .ElementAtOrDefault(multiDialStatius.Item2) .DialogueController.CurrentPanel != null; } public void BindEndActionsToDialogues() { foreach(var finalAction in EndactionEventList) { // finalAction.Key.Key | .Value/ Dialogue .Dialogues .Where(dial => dial.Key == finalAction.Key.Key) .FirstOrDefault() .Value .DialogueSteps .ElementAtOrDefault(finalAction.Key.Value) .SetActionAfterDialogueStep(finalAction.Value) ; } } }