using System.Collections.Generic; using System.Threading; using UnityEngine; using UnityEngine.Events; #nullable enable namespace Yarn.Unity { /// /// A that can present lines and options to the /// user, when it receives them from a . /// /// /// When the Dialogue Runner encounters content that the user should /// see - that is, lines or options - it sends that content to all of the /// dialogue presenters stored in . The /// Dialogue Runner then waits until all Dialogue Presenters have reported that /// they have finished presenting the content. /// /// To use this class, subclass it, and implement its required methods. Once /// you have written your subclass, attach it as a component to a , and add this game object to the list of Dialogue /// presenters in your scene's . /// /// Dialogue Presenters do not need to handle every kind of content that /// the Dialogue Runner might produce. For example, you might have one /// Dialogue Presenter that handles Lines, and another that handles Options. The /// built-in class is an example of this, in that it /// only handles Lines and does nothing when it receives Options. /// /// You may also have multiple Dialogue Presenters that handle the same /// kind of content. For example, you may have a Dialogue Presenter that receives /// Lines and uses them to play voice-over audio, and a second Dialogue Presenter /// that also receives Lines and uses them to display on-screen subtitles. /// /// /// /// public abstract class DialoguePresenterBase : MonoBehaviour { /// /// Called by the to signal that a line /// should be displayed to the user. /// /// /// /// When this method is called, the Dialogue Presenter should present the /// line to the user. The content to present is contained within the /// parameter, which contains information about /// the line in the user's current locale. /// /// /// It's up to the Dialogue Presenter to decide what "presenting" the line /// may mean; for example, showing on-screen text, playing voice-over /// audio, or updating on-screen portraits to show a picture of the /// speaking character. /// /// /// The will wait until the tasks from all /// of its dialogue presenters have completed before continuing to the next /// piece of content. If your dialogue presenter does not need to handle the /// line, it should return immediately. /// /// The value of the /// parameter is produced by the Dialogue Runner's . /// /// /// The default implementation of this method takes no action and /// returns immediately. /// /// /// The line to present. /// A that /// represents whether the dialogue presenter should hurry it its /// presentation of the line, or stop showing the current line. /// A task that completes when the dialogue presenter has finished /// showing the line to the user. /// public abstract YarnTask RunLineAsync(LocalizedLine line, LineCancellationToken token); /// /// Called by the to signal that a set of /// options should be displayed to the user. /// /// /// This method is called when the Dialogue Runner wants to show a /// collection of options that the user should choose from. Each option /// is represented by a object, which /// contains information about the option. /// When this method is called, the Dialogue Presenter should display /// appropriate user interface elements that let the user choose among /// the options. /// This method should await until an option is selected, and then /// return the selected option. If this view doesn't handle options, or /// is otherwise unable to select an option, it should return . The dialogue runner will wait /// for all dialogue views to return, so if a dialogue presenter doesn't or /// can't handle options, it's good practice to return as soon as /// possible. /// /// If the becomes cancelled, /// this means that the dialogue runner no longer needs this Dialogue /// presenter to make a selection, and this method should return as soon as /// possible; its return value will not be used. /// /// /// The default implementation of this method returns . /// /// /// The set of options that should be /// displayed to the user. /// A /// that becomes cancelled when the dialogue runner no longer needs this /// dialogue presenter to return an option. /// A task that indicates which option was selected, or that this dialogue presenter did not select an option. /// /// [System.Obsolete("The LineCancellationToken form of RunOptionsAsync allows for option cancellation and hurrying up and is prefered.")] public virtual YarnTask RunOptionsAsync(DialogueOption[] dialogueOptions, CancellationToken cancellationToken) { return YarnTask.FromResult(null); } #pragma warning disable 0618 public virtual YarnTask RunOptionsAsync(DialogueOption[] dialogueOptions, LineCancellationToken cancellationToken) { return RunOptionsAsync(dialogueOptions, cancellationToken.NextLineToken); } #pragma warning restore 0618 /// Called by the to signal that /// dialogue has started. /// /// This method is called before any content (that is, lines, /// options or commands) are delivered. /// This method is a good place to perform tasks like preparing /// on-screen dialogue UI (for example, turning on a letterboxing /// effect, or making dialogue UI elements visible.) /// /// The default implementation of this method does /// nothing. /// /// A task that represents any work done by this dialogue presenter in order to get ready for dialogue to run. public abstract YarnTask OnDialogueStartedAsync(); /// /// Called by the to signal that the /// dialogue has ended, and no more lines will be delivered. /// /// /// This method is called after the last piece of content (that /// is, lines, options or commands) finished running. /// This method is a good place to perform tasks like dismissing /// on-screen dialogue UI (for example, turning off a letterboxing /// effect, or hiding dialogue UI elements.) /// /// The default implementation of this method does /// nothing. /// /// A task that represents any work done by this dialogue presenter /// in order to clean up after running dialogue. public abstract YarnTask OnDialogueCompleteAsync(); // these are virtual because it's quite likely you don't need them // they are also void instead of YarnTask because currently the VM doesn't wait on node enter/exit so we can't either public virtual void OnNodeEnter(string nodeName) { } public virtual void OnNodeExit(string nodeName) { } public virtual IAsyncTypewriter? Typewriter { get; set; } } }