using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace Framework.Dialogue2 { /// Interface for accessing the widgets of a dialogue canvas instance public class UGuiDialogueWidgets : IDisposable { /// Initializes a new UGui dialogue widget manager /// UGui canvas on which the dialogue widgets are placed public UGuiDialogueWidgets(Canvas uGuiCanvas) { this.uGuiCanvas = uGuiCanvas; } /// Called after the widget controller has been constructed public virtual void Initialize() { this.speechWidget = DiscoverSpeechPanel(); this.choiceWidgets = DiscoverChoiceButtons(); } /// Destroys the canvas public void Dispose() { if(this.uGuiCanvas != null) { this.speechWidget = null; this.choiceWidgets.Clear(); GameObject.Destroy(this.uGuiCanvas); this.uGuiCanvas = null; } } /// The maximum number of choice buttons the dialogue canvas can display /// /// Also see the remarks section of the method, /// if the widget controller implementation creates buttons dynamically, just return /// some ridiculously high number (i.e. int.MaxValue), otherwise, return the number /// of buttons that have been set up on the canvas /// public virtual int MaximumChoiceCount { get { return this.choiceWidgets.Count; } } /// Looks for the speech panel in the widget controller's canvas /// /// This simply goes by the convention that the speech panel game object will have /// the text 'Speech' in its name. /// protected virtual Transform DiscoverSpeechPanel() { Transform speechPanel = null; { Transform parent = this.uGuiCanvas.transform; foreach(Transform child in parent) { if(child.name.Contains("Speech")) { Text textControl = child.GetComponentInChildren(); if(textControl == null) { Debug.LogWarning( "Element '" + child.name + "' on dialogue canvas " + "'" + this.uGuiCanvas.name + "' is not a text control " + "and will not be used as a template." ); } else { speechPanel = child; } } } } // If no suitable panel was found, complain to the user so he knows // why the dialogue UI isn't working if(speechPanel == null) { Debug.LogError( "No speech panel found. " + "Dialogue canvas '" + this.uGuiCanvas.name + "' will be unable to display speech." ); } return speechPanel; } /// Looks for the choice buttons in the widget controller's canvas /// /// /// This simply goes by the convention that the choice button game objects will /// have the text 'Choice' in their names. /// /// /// There are two ways choice buttons can be set up: the first way is to place /// the maximum number of choice buttons you will possibly use on your UGUI canvas /// straight away and hide the ones not used at runtime when dialogue is shown. /// /// /// The other option is to create exactly one choice button and when dialogue is /// shown, duplicate it to obtain the required number of choice buttons. This is /// more complex as it requires the widget controller to figure out where to /// place the additional buttons (i.e. do they stack vertically in some scroll box /// or are there two colums of them, etc.) /// /// /// The default widget controller implementation is therefore assuming option 1 /// (all buttons pre-created) is used. /// /// protected virtual IList DiscoverChoiceButtons() { var choiceButtons = new List(); { Transform parent = this.uGuiCanvas.transform; foreach(Transform child in parent) { if(child.name.Contains("Choice") && !child.name.Contains("Speech")) { Button buttonControl = child.GetComponentInChildren