Browse Source

Renamed DialogController to Dialog

master
chrisgregan 10 years ago
parent
commit
af3dbcbb11
  1. 6
      Assets/Fungus/Dialog/Commands/Say.cs
  2. 2
      Assets/Fungus/Dialog/Commands/SetDialog.cs
  3. 2
      Assets/Fungus/Dialog/Editor/SetDialog.cs
  4. 4
      Assets/Fungus/Dialog/Scripts/Character.cs
  5. 865
      Assets/Fungus/Dialog/Scripts/Dialog.cs
  6. 2
      Assets/Fungus/Dialog/Scripts/Dialog.cs.meta
  7. 235
      Assets/Fungus/Dialog/Scripts/DialogController.cs
  8. 0
      Assets/Fungus/Legacy/Scripts/Button.cs
  9. 0
      Assets/Fungus/Legacy/Scripts/Button.cs.meta
  10. 0
      Assets/Fungus/Legacy/Scripts/GUIButton.cs
  11. 0
      Assets/Fungus/Legacy/Scripts/GUIButton.cs.meta
  12. 4
      Assets/Fungus/Legacy/Scripts/Game.cs
  13. 878
      Assets/Fungus/Legacy/Scripts/LegacyDialog.cs
  14. 2
      Assets/Fungus/Legacy/Scripts/LegacyDialog.cs.meta
  15. BIN
      Assets/Shuttle/NewDialog.unity

6
Assets/Fungus/Dialog/Commands/Say.cs

@ -9,7 +9,7 @@ namespace Fungus.Script
[HelpText("Writes a line of story text to the dialog. A list of options can be specified for the player to choose from. Use a non-zero timeout to give the player a limited time to choose.")]
public class Say : FungusCommand
{
static public DialogController dialogController;
static public Dialog dialogController;
public Character character;
public string storyText;
@ -50,10 +50,10 @@ namespace Fungus.Script
if (options.Count > 0)
{
List<DialogController.Option> dialogOptions = new List<DialogController.Option>();
List<Dialog.Option> dialogOptions = new List<Dialog.Option>();
foreach (SayOption sayOption in options)
{
DialogController.Option dialogOption = new DialogController.Option();
Dialog.Option dialogOption = new Dialog.Option();
dialogOption.text = sayOption.optionText;
Sequence onSelectSequence = sayOption.targetSequence;

2
Assets/Fungus/Dialog/Commands/SetDialog.cs

@ -10,7 +10,7 @@ namespace Fungus.Script
[HelpText("Sets the active dialog for displaying story text with the Say command.")]
public class SetDialog : FungusCommand
{
public DialogController dialogController;
public Dialog dialogController;
public override void OnEnter()
{

2
Assets/Fungus/Dialog/Editor/SetDialog.cs

@ -17,7 +17,7 @@ namespace Fungus.Script
EditorGUI.BeginChangeCheck();
DialogController dialogController = FungusCommandEditor.ObjectField<DialogController>(new GUIContent("Active Dialog", "Dialog to use when displaying Say command story text"),
Dialog dialogController = FungusCommandEditor.ObjectField<Dialog>(new GUIContent("Active Dialog", "Dialog to use when displaying Say command story text"),
new GUIContent("<None>"),
t.dialogController);
if (EditorGUI.EndChangeCheck())

4
Assets/Fungus/Dialog/Scripts/Character.cs

@ -1,4 +1,4 @@
using UnityEngine;
using UnityEngine;
using System.Collections;
namespace Fungus.Script
@ -8,7 +8,7 @@ namespace Fungus.Script
{
public string characterName;
public Sprite characterImage;
public DialogController.DialogSide dialogSide;
public Dialog.DialogSide dialogSide;
public Color characterColor;
}

865
Assets/Fungus/Dialog/Scripts/Dialog.cs

@ -1,878 +1,235 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Fungus
namespace Fungus.Script
{
/**
* Permitted states for Dialogs.
*/
public enum DialogMode
{
/// Dialog has no pending content to display so is not shown.
Idle,
/// Dialog is currently writing out content.
Writing,
/// Dialog has finished writing out content and is waiting for player input.
Waiting
}
/**
* Interface for Dialog implementations.
* This allows us to introduce new types of Dialog in future.
*/
public interface IDialog
{
/**
* Returns the current state of the Dialog.
*/
DialogMode GetDialogMode();
/**
* Display a line of story text.
* If any options have previously been added using AddOption(), these will be displayed and the
* user must choose an option to continue. The sayAction parameter is ignored
* @param sayText The line of story text to be displayed.
* @param sayAction Delegate method to call when the player taps to continue.
*/
void Say(string sayText, Action sayAction);
/**
* Clear the current list of options previously added using AddOption().
*/
void ClearOptions();
/**
* Add an option to the list of options to be displayed on the next call to Say().
* @param optionText Text to display on the button for the option.
* @param optionAction Delegate method to call when the option button is pressed.
*/
void AddOption(string optionText, Action optionAction);
/**
* Sets a time limit for the player to choose between multiple options.
* If the player fails to make a choice in time then the timeoutAction delegate method is called.
* This setting only applies to the next Say() command and will be reset afterwards.
* @timeoutDuration Length of time for the player to choose an option.
* @timeoutAction Delegate method to call when player fails to choose an option.
*/
void SetTimeout(float timeoutDuration, Action timeoutAction);
}
[ExecuteInEditMode]
public class Dialog : MonoBehaviour, IDialog
{
/**
* Padding values for each side of the dialog.
* Values are in normalized screen coords [0..1]
*/
[Serializable]
public class Layout
{
/**
* Push the left dialog edge away from the left side of the screen.
*/
[Tooltip("Push the left dialog edge away from the left side of the screen.")]
public bool leftSpace = false;
/**
* Push the top dialog edge away from the top side of the screen.
*/
[Tooltip("Push the top dialog edge away from the top side of the screen.")]
public bool topSpace = true;
/**
* Push the right dialog edge away from the right side of the screen.
*/
[Tooltip("Push the right dialog edge away from the right side of the screen.")]
public bool rightSpace = false;
/**
* Push the bottom dialog edge away from the bottom side of the screen.
*/
[Tooltip("Push the bottom dialog edge away from the bottom side of the screen.")]
public bool bottomSpace = false;
/**
* Minimum dimensions of the dialog in normalized screen coordinates [0..1].
* The dialog may expand beyond these dimensions to fit content.
*/
[Tooltip("Minimum dimensions of the dialog in normalized screen coordinates [0..1].")]
public Vector2 size = new Vector2(1f, 0.25f);
/**
* Offset the dialog relative to the top left corner of the screen.
* Coordinates are in normalized screen coordinates [0..1]
*/
[Tooltip("Offset the dialog relative to the top left corner of the screen.")]
public Vector2 offset;
}
/**
* Layout values used to control size and position of the dialog.
*/
[Tooltip("Layout values used to control size and position of the dialog.")]
public Layout layout;
/**
* Defines the dialog display properties of a game character.
*/
[System.Serializable]
public class Character
{
/**
* Side of screen to display character image.
*/
public enum ImageSide
{
/// Display image on the left side of the dialog.
Left,
/// Display image on the right side of the dialog.
Right
}
/**
* Identifier for this character for use with the SetCharacter() command.
*/
[Tooltip("Identifier for this character for use with the SetCharacter() command.")]
public string characterID;
/**
* Name text to display for the character on the dialog.
* If empty then the name field is not displayed.
*/
[Tooltip("Name text to display for the character on the dialog.")]
public string name;
/**
* The color of the name text label.
* This always overrides any color value specified in the NameStyle property.
*/
[Tooltip("The color of the name text label.")]
public Color nameColor;
/**
* Image to display for the character.
* If no image is specified then no character image will be displayed.
*/
[Tooltip("Image to display for the character.")]
public Texture2D image;
/**
* Side of dialog where character image will be displayed.
*/
[Tooltip("Side of dialog where character image will be displayed.")]
public ImageSide imageSide;
}
/**
* List of game characters that can be displayed using this dialog.
*/
[Tooltip("List of game characters that can be displayed using this dialog.")]
public Character[] characters;
/**
* Active character to use when displaying dialog (set using the SetCharacter() command).
*/
[Tooltip("Active character to use when displaying dialog.")]
public int activeCharacter;
/**
* Writing speed for say text in characters per second.
*/
[Range(0, 1000)]
[Tooltip("Writing speed for say text in characters per second.")]
public int writingSpeed = 100;
/**
* Sound to play while text is being written in the dialog.
*/
[Tooltip("Sound to play while text is being written in the dialog.")]
public AudioClip writingSound;
/**
* Loop the writing sound as long as text is being written.
*/
[Tooltip("Loop the writing sound while text is being written.")]
public bool loopWritingSound = true;
/**
* Sound effect to play when the player taps to continue.
*/
[Tooltip("Sound effect to play when the player taps to continue.")]
public AudioClip continueSound;
/**
* Icon to display under the story text when waiting for player to tap to continue.
*/
[Tooltip("Icon to display under the story text when waiting for player to tap to continue.")]
public Texture2D continueIcon;
/**
* Number of buttons to display in the same row when showing multiple options.
*/
[Range(0, 10)]
[Tooltip("Number of buttons to display in the same row when showing multiple options.")]
public int buttonsPerRow = 2;
/**
* Minimum width of each button as a fraction of the screen width [0..1].
* This is useful to create a column of buttons with matching width.
*/
[Range(0, 1)]
[Tooltip("Minimum width of each button as a fraction of the screen width [0..1].")]
public float minButtonWidth = 0;
/**
* Padding values for each side of the character image.
*/
[System.Serializable]
public class ImagePadding
{
/**
* Padding to apply to left side of image as a fraction of screen height [-2..2].
*/
[Range(-2,2)]
[Tooltip("Padding to apply to left side of image as a fraction of screen height [-2..2].")]
public float left;
/**
* Padding to apply to right side of image as a fraction of screen height [-2..2].
*/
[Range(-2,2)]
[Tooltip("Padding to apply to right side of image as a fraction of screen height [-2..2].")]
public float right;
/**
* Padding to apply to top side of image as a fraction of screen height [-1..1].
*/
[Range(-1,1)]
[Tooltip("Padding to apply to top side of image as a fraction of screen height [-1..1].")]
public float top;
/**
* Padding to apply to bottom side of image as a fraction of screen height [-1..1].
*/
[Range(-1,1)]
[Tooltip("Padding to apply to bottom side of image as a fraction of screen height [-1..1].")]
public float bottom;
}
/**
* Padding offset to apply around the character image.
*/
[Tooltip("Padding offset to apply around the character image.")]
public ImagePadding imagePadding;
/**
* Scale of character image, specified as a fraction of current screen height [0..1].
*/
[Range(0, 1)]
[Tooltip("Scale of character image, specified as a fraction of current screen height [0..1].")]
public float imageScale = 0.25f;
/**
* Animation frames for multiple choice time indicator.
*/
[Tooltip("Animation frames for multiple choice time indicator.")]
public Texture2D[] timerAnimation;
/**
* Scale of timer image, specified as a fraction of current screen height [0..1].
*/
[Range(0, 1)]
[Tooltip("Scale of timer image, specified as a fraction of current screen height [0..1].")]
public float timerScale = 0.2f;
/**
* Sound effect to play when time indicator advances.
*/
[Tooltip("Sound effect to play when time indicator advances.")]
public AudioClip timerSound;
/**
* Style for dialog box background.
*/
[Tooltip("Style for dialog box background.")]
public GUIStyle boxStyle;
/**
* Style for name text.
*/
[Tooltip("Style for name text.")]
public GUIStyle nameTextStyle;
/**
* Style for say text.
*/
[Tooltip("Style for say text.")]
public GUIStyle sayTextStyle;
/**
* Style for option buttons
*/
[Tooltip("Style for option buttons.")]
public GUIStyle buttonStyle;
DialogMode dialogMode;
public DialogMode GetDialogMode()
{
return dialogMode;
}
class Option
public class Dialog : MonoBehaviour
{
public string optionText;
public Action optionAction;
public Option(string _optionText, Action _optionAction)
public enum DialogSide
{
optionText = _optionText;
optionAction = _optionAction;
}
}
List<Option> options = new List<Option>();
float timeoutDuration;
Action timeoutAction;
float timeoutTimer;
int timeoutAnimationIndex;
string sayText = "";
string previousSayText = "";
string displayedSayText = "";
Action deferredAction;
Action continueAction;
float continueTimer;
bool instantCompleteText;
bool fullscreen;
// Cache scaled GUIStyle objects so we're not creating lots of new objects every frame
GUIStyle cachedBoxStyle;
GUIStyle cachedNameTextStyle;
GUIStyle cachedSayTextStyle;
GUIStyle cachedButtonStyle;
Left,
Right
};
void Start()
public class Option
{
if (!Application.isPlaying)
{
return;
public string text;
public Action onSelect;
}
CacheScaledStyles();
public Canvas dialogCanvas;
public List<UnityEngine.UI.Button> optionButtons = new List<UnityEngine.UI.Button>();
public Text nameText;
public Text storyText;
public Image continueImage;
public Image leftImage;
public Image rightImage;
fullscreen = Screen.fullScreen;
}
void Update()
{
writingSpeed = Math.Max(writingSpeed, 0);
buttonsPerRow = Math.Max(buttonsPerRow, 1);
minButtonWidth = Mathf.Max(minButtonWidth, 0);
imageScale = Mathf.Max(imageScale, 0);
timerScale = Mathf.Max(timerScale, 0);
layout.size.x = Mathf.Clamp01(layout.size.x);
layout.size.y = Mathf.Clamp01(layout.size.y);
layout.offset.x = Mathf.Clamp01(layout.offset.x);
layout.offset.y = Mathf.Clamp01(layout.offset.y);
List<Action> optionActions = new List<Action>();
if (!Application.isPlaying)
public void ShowDialog(bool visible)
{
return;
}
if (continueTimer > 0)
if (dialogCanvas != null)
{
continueTimer -= Time.deltaTime;
continueTimer = Mathf.Max(continueTimer, 0f);
dialogCanvas.gameObject.SetActive(visible);
}
if (sayText.Length == 0)
{
dialogMode = DialogMode.Idle;
}
// Check if the sayText field has been modified directly.
// If that has happened, then write the text with no Action
if (sayText != previousSayText &&
sayText.Length > 0)
public void SetCharacter(Character character)
{
StopAllCoroutines();
Say(sayText, null);
}
if (timeoutTimer > 0)
if (character == null)
{
timeoutTimer -= Time.deltaTime;
timeoutTimer = Mathf.Max(timeoutTimer, 0f);
if (leftImage != null)
leftImage.enabled = false;
if (rightImage != null)
rightImage.enabled = false;
if (nameText != null)
nameText.text = "";
}
// Update cached GUIStyles when running in editor or when switching to/from fullscreen
if (Application.isEditor ||
fullscreen != Screen.fullScreen)
else
{
CacheScaledStyles();
fullscreen = Screen.fullScreen;
SetCharacterImage(character.characterImage, character.dialogSide);
SetCharacterName(character.name, character.characterColor);
}
}
void CacheScaledStyles()
public void SetCharacterImage(Sprite image, DialogSide side)
{
cachedBoxStyle = ScaleFontSize(boxStyle);
cachedNameTextStyle = ScaleFontSize(nameTextStyle);
cachedSayTextStyle = ScaleFontSize(sayTextStyle);
cachedButtonStyle = ScaleFontSize(buttonStyle);
}
public void Say(string _sayText, Action sayAction)
if (leftImage != null)
{
string copyText = _sayText;
// Hack: Handle Say(""); by writing a single space character.
if (copyText.Length == 0)
if (image != null &&
side == DialogSide.Left)
{
copyText = " ";
leftImage.sprite = image;
leftImage.enabled = true;
}
continueAction = sayAction;
previousSayText = copyText;
if (timeoutDuration > 0 &&
options.Count > 0)
else
{
// Activate timeout timer
timeoutTimer = timeoutDuration;
leftImage.enabled = false;
}
WriteSayText(copyText);
}
void WriteSayText(string _sayText)
if (rightImage != null)
{
// Disable quick continue for a short period to prevent accidental taps
continueTimer = 0.4f;
instantCompleteText = false;
sayText = _sayText;
if (_sayText.Contains("<"))
rightImage.sprite = null;
if (image != null &&
side == DialogSide.Right)
{
// Hack to avoid displaying partial color tag text - write instantly
displayedSayText = _sayText;
dialogMode = DialogMode.Waiting;
rightImage.sprite = image;
rightImage.enabled = true;
}
else
{
// Use a coroutine to write the story text out over time
StartCoroutine(WriteStoryInternal());
rightImage.sprite = null;
rightImage.enabled = false;
}
}
// Coroutine to write story text out over a period of time
IEnumerator WriteStoryInternal()
{
// Zero CPS means write instantly
if (writingSpeed == 0)
{
displayedSayText = sayText;
yield break;
}
GameObject typingAudio = null;
if (writingSound != null)
{
typingAudio = new GameObject("WritingSound");
typingAudio.AddComponent<AudioSource>();
typingAudio.audio.clip = writingSound;
typingAudio.audio.loop = loopWritingSound;
typingAudio.audio.Play();
}
dialogMode = DialogMode.Writing;
displayedSayText = "";
// Make one character visible at a time
float writeDelay = (1f / (float)writingSpeed);
float timeAccumulator = 0f;
int i = 0;
while (true)
public void SetCharacterName(string name, Color color)
{
if (instantCompleteText)
if (nameText != null)
{
instantCompleteText = false;
displayedSayText = sayText;
break;
nameText.text = name;
nameText.color = color;
}
timeAccumulator += Time.deltaTime;
while (timeAccumulator > writeDelay)
{
i++;
timeAccumulator -= writeDelay;
}
if (i >= sayText.Length)
public void Say(string text, Action onComplete)
{
displayedSayText = sayText;
break;
}
else
{
string left = sayText.Substring(0, i + 1);
string right = sayText.Substring(i + 1);
displayedSayText = left;
displayedSayText += "<color=#FFFFFF00>";
displayedSayText += right;
displayedSayText += "</color>";
}
Clear();
yield return null;
}
dialogMode = DialogMode.Waiting;
if (typingAudio != null)
if (storyText != null)
{
Destroy(typingAudio);
}
storyText.text = text;
}
GUIStyle ScaleFontSize(GUIStyle style)
{
GUIStyle styleCopy = new GUIStyle(style);
styleCopy.fontSize = Mathf.RoundToInt(styleCopy.fontSize * ((float)Screen.height / 768f));
return styleCopy;
}
// TODO: Wait for text to finish writing
public void ClearOptions()
{
options.Clear();
ShowContinueIcon(true);
StartCoroutine(WaitForInput(onComplete));
}
public void AddOption(string optionText, Action optionAction)
public void Say(string text, List<Option> options)
{
options.Add(new Option(optionText, optionAction));
}
Clear();
public void SetTimeout(float _timeoutDuration, Action _timeoutAction)
if (storyText != null)
{
timeoutDuration = _timeoutDuration;
timeoutAction = _timeoutAction;
storyText.text = text;
}
public void SetCharacter(string characterID)
{
for (int i = 0; i < characters.Length; ++i)
{
if (characters[i].characterID == characterID)
ShowContinueIcon(false);
foreach (Option option in options)
{
activeCharacter = i;
return;
}
AddOption(option.text, option.onSelect);
}
Debug.Log ("Failed to find character ID " + characterID);
}
public virtual void OnGUI()
IEnumerator WaitForInput(Action onComplete)
{
if (!Application.isPlaying ||
dialogMode == DialogMode.Idle ||
characters.Length == 0 ||
activeCharacter >= characters.Length)
// TODO: Handle touch input
while (!Input.GetMouseButtonDown(0))
{
return;
yield return null;
}
Rect areaRect = new Rect(layout.offset.x * Screen.width, layout.offset.y * Screen.height, Screen.width, Screen.height);
Rect sideImageRect = new Rect();
Rect dialogRect = new Rect();
// The left and right padding values are also calculated based on Screen.height to give
// consistent padding regardless of the screen aspect ratio
RectOffset imagePaddingRect = new RectOffset(Mathf.RoundToInt(imagePadding.left * Screen.height),
Mathf.RoundToInt(imagePadding.right * Screen.height),
Mathf.RoundToInt(imagePadding.top * Screen.height),
Mathf.RoundToInt(imagePadding.bottom * Screen.height));
Character character = characters[activeCharacter];
Clear();
GUILayout.BeginArea(areaRect);
if (onComplete != null)
{
if (layout.topSpace)
{
GUILayout.FlexibleSpace();
onComplete();
}
GUILayout.BeginHorizontal();
{
if (layout.leftSpace)
{
GUILayout.FlexibleSpace();
}
GUILayout.BeginHorizontal(cachedBoxStyle, GUILayout.MinWidth(Screen.width * layout.size.x), GUILayout.MinHeight(Screen.height * layout.size.y));
void ShowContinueIcon(bool visible)
{
if (character.imageSide == Character.ImageSide.Left &&
character.image != null)
if (continueImage != null)
{
// Reserve a rect for the side image based on the current screen height and imageScale
float sideImageHeight = Screen.height * imageScale;
float sideImageWidth = (sideImageHeight / character.image.height) * character.image.width;
float w = sideImageWidth + imagePaddingRect.left + imagePaddingRect.right;
float h = sideImageHeight + imagePaddingRect.top + imagePaddingRect.bottom;
sideImageRect = GUILayoutUtility.GetRect(w, h, GUILayout.Width(w), GUILayout.Height(h));
continueImage.enabled = visible;
}
else if (character.imageSide == Character.ImageSide.Right)
{
DrawTimer();
}
GUILayout.BeginVertical(GUILayout.ExpandWidth(false));
void Clear()
{
if (character.name.Length > 0)
{
cachedNameTextStyle.normal.textColor = character.nameColor;
GUILayout.Label(new GUIContent(character.name), cachedNameTextStyle);
}
GUILayout.FlexibleSpace();
GUILayout.Label(new GUIContent(displayedSayText), cachedSayTextStyle);
GUILayout.FlexibleSpace();
// Show buttons for player options, or the continue icon if there are no options
if (options.Count > 0)
{
GUILayout.BeginHorizontal();
{
GUILayout.BeginVertical();
{
int buttonCount = 0;
for (int i = 0; i < options.Count; ++i)
{
if (buttonCount == 0)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
ClearStoryText();
ClearOptions();
}
buttonCount++;
if (GUILayout.Button(options[i].optionText, cachedButtonStyle, GUILayout.MinWidth(Screen.width * minButtonWidth)))
{
AudioSource.PlayClipAtPoint(continueSound, new Vector3());
if (options[i].optionAction == null)
void ClearStoryText()
{
deferredAction = DoNullAction;
}
else
if (storyText != null)
{
deferredAction = options[i].optionAction;
storyText.text = "";
}
}
if (buttonCount == buttonsPerRow ||
i == options.Count - 1)
void ClearOptions()
{
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
buttonCount = 0;
}
}
}
GUILayout.EndVertical();
}
GUILayout.EndHorizontal();
}
else if (continueIcon != null)
if (optionButtons == null)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
Rect continueButtonRect = GUILayoutUtility.GetRect(continueIcon.width,
continueIcon.height,
GUILayout.MaxWidth(continueIcon.width),
GUILayout.MaxHeight(continueIcon.height));
if (dialogMode == DialogMode.Waiting)
{
continueButtonRect.y += Mathf.Sin(Time.timeSinceLevelLoad * 15f) * (float)(continueIcon.height * 0.2f);
GUI.DrawTexture(continueButtonRect, continueIcon);
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
return;
}
GUILayout.FlexibleSpace();
}
GUILayout.EndVertical();
optionActions.Clear();
if (character.imageSide == Character.ImageSide.Right &&
character.image != null)
foreach (UnityEngine.UI.Button button in optionButtons)
{
// Reserve a rect for the side image based on the current screen height and imageScale
float sideImageHeight = Screen.height * imageScale;
float sideImageWidth = (sideImageHeight / character.image.height) * character.image.width;
float w = sideImageWidth + imagePaddingRect.left + imagePaddingRect.right;
float h = sideImageHeight + imagePaddingRect.top + imagePaddingRect.bottom;
sideImageRect = GUILayoutUtility.GetRect(w, h, GUILayout.Width(w), GUILayout.Height(h));
}
else if (character.imageSide == Character.ImageSide.Left)
if (button != null)
{
DrawTimer();
button.gameObject.SetActive(false);
}
}
GUILayout.EndHorizontal();
// Get rect of dialog for testing mouse hit later on
dialogRect = GUILayoutUtility.GetLastRect();
if (layout.rightSpace)
{
GUILayout.FlexibleSpace();
}
}
GUILayout.EndHorizontal();
if (layout.bottomSpace)
bool AddOption(string text, Action action)
{
GUILayout.FlexibleSpace();
}
}
GUILayout.EndArea();
if (character.image != null)
if (optionButtons == null)
{
// Adjust side image rect based on aspect ratio of the image.
float sideImageHeight = character.image.height * ((sideImageRect.width - imagePaddingRect.left - imagePaddingRect.right) / character.image.width);
sideImageRect.yMax = sideImageRect.yMin + sideImageHeight + imagePaddingRect.bottom + imagePaddingRect.top;
sideImageRect = imagePaddingRect.Remove(sideImageRect);
// Adjust rect based on layout offset
sideImageRect.x += areaRect.x;
sideImageRect.y += areaRect.y;
// Draw side image
GUI.DrawTexture(sideImageRect, character.image);
return false;
}
bool clickedOnDialog = (Input.GetMouseButtonUp(0) && dialogRect.Contains(Event.current.mousePosition));
if (dialogMode == DialogMode.Writing)
bool addedOption = false;
foreach (UnityEngine.UI.Button button in optionButtons)
{
if (clickedOnDialog || Input.GetKeyUp("space"))
if (!button.gameObject.activeSelf)
{
instantCompleteText = true;
}
}
button.gameObject.SetActive(true);
if (dialogMode == DialogMode.Waiting)
{
// Player can continue by clicking anywhere
if (options.Count == 0 &&
continueTimer == 0 &&
(clickedOnDialog || Input.GetKeyUp("space")))
Text textComponent = button.GetComponentInChildren<Text>();
if (textComponent != null)
{
if (continueSound != null)
{
AudioSource.PlayClipAtPoint(continueSound, new Vector3());
textComponent.text = text;
}
if (continueAction == null)
{
deferredAction = DoNullAction;
}
else
{
deferredAction = continueAction;
}
}
optionActions.Add(action);
// Check if timeout timer has expired
if (options.Count > 0 &&
timeoutDuration > 0 &&
timeoutTimer == 0)
{
deferredAction = timeoutAction;
addedOption = true;
break;
}
}
// Execute any deferred actions on the last call to OnGUI
if (Event.current.type == EventType.Repaint)
{
if (deferredAction != null)
{
Action tempAction = deferredAction;
displayedSayText = "";
sayText = "";
deferredAction = null;
dialogMode = DialogMode.Idle;
ClearOptions();
timeoutAction = null;
timeoutDuration = 0;
timeoutTimer = 0;
timeoutAnimationIndex = 0;
tempAction();
}
}
return addedOption;
}
void DrawTimer()
{
if (timeoutTimer > 0 &&
timerAnimation.Length > 0)
{
GUILayout.BeginHorizontal();
public void SelectOption(int index)
{
GUILayout.FlexibleSpace();
GUILayout.BeginVertical();
if (index < optionActions.Count)
{
GUILayout.FlexibleSpace();
float t = 1f - timeoutTimer / timeoutDuration;
int index = Mathf.RoundToInt(Mathf.Lerp(0, timerAnimation.Length - 1, t));
// Play a sound effect for each animation frame
if (timeoutAnimationIndex != index &&
timerSound != null)
Action optionAction = optionActions[index];
if (optionAction != null)
{
AudioSource.PlayClipAtPoint(timerSound, Vector3.zero);
Clear();
optionAction();
}
timeoutAnimationIndex = index;
float height = Screen.height * timerScale;
GUILayout.Box(timerAnimation[timeoutAnimationIndex], new GUIStyle(), GUILayout.Height(height));
GUILayout.FlexibleSpace();
}
GUILayout.EndVertical();
GUILayout.FlexibleSpace();
}
GUILayout.EndHorizontal();
}
}
void DoNullAction()
{}
}
}

2
Assets/Fungus/Dialog/Scripts/Dialog.cs.meta

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d5fe4de5a03e34488bb65c75039a328d
guid: 3a0bbe22c246e4c78ad8e9816cbae9d5
MonoImporter:
serializedVersion: 2
defaultReferences: []

235
Assets/Fungus/Dialog/Scripts/DialogController.cs

@ -1,235 +0,0 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Fungus.Script
{
public class DialogController : MonoBehaviour
{
public enum DialogSide
{
Left,
Right
};
public class Option
{
public string text;
public Action onSelect;
}
public Canvas dialogCanvas;
public List<UnityEngine.UI.Button> optionButtons = new List<UnityEngine.UI.Button>();
public Text nameText;
public Text storyText;
public Image continueImage;
public Image leftImage;
public Image rightImage;
List<Action> optionActions = new List<Action>();
public void ShowDialog(bool visible)
{
if (dialogCanvas != null)
{
dialogCanvas.gameObject.SetActive(visible);
}
}
public void SetCharacter(Character character)
{
if (character == null)
{
if (leftImage != null)
leftImage.enabled = false;
if (rightImage != null)
rightImage.enabled = false;
if (nameText != null)
nameText.text = "";
}
else
{
SetCharacterImage(character.characterImage, character.dialogSide);
SetCharacterName(character.name, character.characterColor);
}
}
public void SetCharacterImage(Sprite image, DialogSide side)
{
if (leftImage != null)
{
if (image != null &&
side == DialogSide.Left)
{
leftImage.sprite = image;
leftImage.enabled = true;
}
else
{
leftImage.enabled = false;
}
}
if (rightImage != null)
{
rightImage.sprite = null;
if (image != null &&
side == DialogSide.Right)
{
rightImage.sprite = image;
rightImage.enabled = true;
}
else
{
rightImage.sprite = null;
rightImage.enabled = false;
}
}
}
public void SetCharacterName(string name, Color color)
{
if (nameText != null)
{
nameText.text = name;
nameText.color = color;
}
}
public void Say(string text, Action onComplete)
{
Clear();
if (storyText != null)
{
storyText.text = text;
}
// TODO: Wait for text to finish writing
ShowContinueIcon(true);
StartCoroutine(WaitForInput(onComplete));
}
public void Say(string text, List<Option> options)
{
Clear();
if (storyText != null)
{
storyText.text = text;
}
ShowContinueIcon(false);
foreach (Option option in options)
{
AddOption(option.text, option.onSelect);
}
}
IEnumerator WaitForInput(Action onComplete)
{
// TODO: Handle touch input
while (!Input.GetMouseButtonDown(0))
{
yield return null;
}
Clear();
if (onComplete != null)
{
onComplete();
}
}
void ShowContinueIcon(bool visible)
{
if (continueImage != null)
{
continueImage.enabled = visible;
}
}
void Clear()
{
ClearStoryText();
ClearOptions();
}
void ClearStoryText()
{
if (storyText != null)
{
storyText.text = "";
}
}
void ClearOptions()
{
if (optionButtons == null)
{
return;
}
optionActions.Clear();
foreach (UnityEngine.UI.Button button in optionButtons)
{
if (button != null)
{
button.gameObject.SetActive(false);
}
}
}
bool AddOption(string text, Action action)
{
if (optionButtons == null)
{
return false;
}
bool addedOption = false;
foreach (UnityEngine.UI.Button button in optionButtons)
{
if (!button.gameObject.activeSelf)
{
button.gameObject.SetActive(true);
Text textComponent = button.GetComponentInChildren<Text>();
if (textComponent != null)
{
textComponent.text = text;
}
optionActions.Add(action);
addedOption = true;
break;
}
}
return addedOption;
}
public void SelectOption(int index)
{
if (index < optionActions.Count)
{
Action optionAction = optionActions[index];
if (optionAction != null)
{
Clear();
optionAction();
}
}
}
}
}

0
Assets/Fungus/Sprite/Scripts/Button.cs → Assets/Fungus/Legacy/Scripts/Button.cs

0
Assets/Fungus/Sprite/Scripts/Button.cs.meta → Assets/Fungus/Legacy/Scripts/Button.cs.meta

0
Assets/Fungus/Sprite/Scripts/GUIButton.cs → Assets/Fungus/Legacy/Scripts/GUIButton.cs

0
Assets/Fungus/Sprite/Scripts/GUIButton.cs.meta → Assets/Fungus/Legacy/Scripts/GUIButton.cs.meta

4
Assets/Fungus/Legacy/Scripts/Game.cs

@ -15,7 +15,7 @@ namespace Fungus
/**
* Manages global game state and movement between rooms.
*/
[RequireComponent(typeof(Dialog))]
[RequireComponent(typeof(LegacyDialog))]
public class Game : MonoBehaviour
{
/**
@ -36,7 +36,7 @@ namespace Fungus
* Currently active Dialog object used to display character text and menus.
*/
[Tooltip("Currently active Dialog object used to display character text and menus.")]
public Dialog dialog;
public LegacyDialog dialog;
float autoHideButtonTimer;

878
Assets/Fungus/Legacy/Scripts/LegacyDialog.cs

@ -0,0 +1,878 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Fungus
{
/**
* Permitted states for Dialogs.
*/
public enum DialogMode
{
/// Dialog has no pending content to display so is not shown.
Idle,
/// Dialog is currently writing out content.
Writing,
/// Dialog has finished writing out content and is waiting for player input.
Waiting
}
/**
* Interface for Dialog implementations.
* This allows us to introduce new types of Dialog in future.
*/
public interface IDialog
{
/**
* Returns the current state of the Dialog.
*/
DialogMode GetDialogMode();
/**
* Display a line of story text.
* If any options have previously been added using AddOption(), these will be displayed and the
* user must choose an option to continue. The sayAction parameter is ignored
* @param sayText The line of story text to be displayed.
* @param sayAction Delegate method to call when the player taps to continue.
*/
void Say(string sayText, Action sayAction);
/**
* Clear the current list of options previously added using AddOption().
*/
void ClearOptions();
/**
* Add an option to the list of options to be displayed on the next call to Say().
* @param optionText Text to display on the button for the option.
* @param optionAction Delegate method to call when the option button is pressed.
*/
void AddOption(string optionText, Action optionAction);
/**
* Sets a time limit for the player to choose between multiple options.
* If the player fails to make a choice in time then the timeoutAction delegate method is called.
* This setting only applies to the next Say() command and will be reset afterwards.
* @timeoutDuration Length of time for the player to choose an option.
* @timeoutAction Delegate method to call when player fails to choose an option.
*/
void SetTimeout(float timeoutDuration, Action timeoutAction);
}
[ExecuteInEditMode]
public class LegacyDialog : MonoBehaviour, IDialog
{
/**
* Padding values for each side of the dialog.
* Values are in normalized screen coords [0..1]
*/
[Serializable]
public class Layout
{
/**
* Push the left dialog edge away from the left side of the screen.
*/
[Tooltip("Push the left dialog edge away from the left side of the screen.")]
public bool leftSpace = false;
/**
* Push the top dialog edge away from the top side of the screen.
*/
[Tooltip("Push the top dialog edge away from the top side of the screen.")]
public bool topSpace = true;
/**
* Push the right dialog edge away from the right side of the screen.
*/
[Tooltip("Push the right dialog edge away from the right side of the screen.")]
public bool rightSpace = false;
/**
* Push the bottom dialog edge away from the bottom side of the screen.
*/
[Tooltip("Push the bottom dialog edge away from the bottom side of the screen.")]
public bool bottomSpace = false;
/**
* Minimum dimensions of the dialog in normalized screen coordinates [0..1].
* The dialog may expand beyond these dimensions to fit content.
*/
[Tooltip("Minimum dimensions of the dialog in normalized screen coordinates [0..1].")]
public Vector2 size = new Vector2(1f, 0.25f);
/**
* Offset the dialog relative to the top left corner of the screen.
* Coordinates are in normalized screen coordinates [0..1]
*/
[Tooltip("Offset the dialog relative to the top left corner of the screen.")]
public Vector2 offset;
}
/**
* Layout values used to control size and position of the dialog.
*/
[Tooltip("Layout values used to control size and position of the dialog.")]
public Layout layout;
/**
* Defines the dialog display properties of a game character.
*/
[System.Serializable]
public class Character
{
/**
* Side of screen to display character image.
*/
public enum ImageSide
{
/// Display image on the left side of the dialog.
Left,
/// Display image on the right side of the dialog.
Right
}
/**
* Identifier for this character for use with the SetCharacter() command.
*/
[Tooltip("Identifier for this character for use with the SetCharacter() command.")]
public string characterID;
/**
* Name text to display for the character on the dialog.
* If empty then the name field is not displayed.
*/
[Tooltip("Name text to display for the character on the dialog.")]
public string name;
/**
* The color of the name text label.
* This always overrides any color value specified in the NameStyle property.
*/
[Tooltip("The color of the name text label.")]
public Color nameColor;
/**
* Image to display for the character.
* If no image is specified then no character image will be displayed.
*/
[Tooltip("Image to display for the character.")]
public Texture2D image;
/**
* Side of dialog where character image will be displayed.
*/
[Tooltip("Side of dialog where character image will be displayed.")]
public ImageSide imageSide;
}
/**
* List of game characters that can be displayed using this dialog.
*/
[Tooltip("List of game characters that can be displayed using this dialog.")]
public Character[] characters;
/**
* Active character to use when displaying dialog (set using the SetCharacter() command).
*/
[Tooltip("Active character to use when displaying dialog.")]
public int activeCharacter;
/**
* Writing speed for say text in characters per second.
*/
[Range(0, 1000)]
[Tooltip("Writing speed for say text in characters per second.")]
public int writingSpeed = 100;
/**
* Sound to play while text is being written in the dialog.
*/
[Tooltip("Sound to play while text is being written in the dialog.")]
public AudioClip writingSound;
/**
* Loop the writing sound as long as text is being written.
*/
[Tooltip("Loop the writing sound while text is being written.")]
public bool loopWritingSound = true;
/**
* Sound effect to play when the player taps to continue.
*/
[Tooltip("Sound effect to play when the player taps to continue.")]
public AudioClip continueSound;
/**
* Icon to display under the story text when waiting for player to tap to continue.
*/
[Tooltip("Icon to display under the story text when waiting for player to tap to continue.")]
public Texture2D continueIcon;
/**
* Number of buttons to display in the same row when showing multiple options.
*/
[Range(0, 10)]
[Tooltip("Number of buttons to display in the same row when showing multiple options.")]
public int buttonsPerRow = 2;
/**
* Minimum width of each button as a fraction of the screen width [0..1].
* This is useful to create a column of buttons with matching width.
*/
[Range(0, 1)]
[Tooltip("Minimum width of each button as a fraction of the screen width [0..1].")]
public float minButtonWidth = 0;
/**
* Padding values for each side of the character image.
*/
[System.Serializable]
public class ImagePadding
{
/**
* Padding to apply to left side of image as a fraction of screen height [-2..2].
*/
[Range(-2,2)]
[Tooltip("Padding to apply to left side of image as a fraction of screen height [-2..2].")]
public float left;
/**
* Padding to apply to right side of image as a fraction of screen height [-2..2].
*/
[Range(-2,2)]
[Tooltip("Padding to apply to right side of image as a fraction of screen height [-2..2].")]
public float right;
/**
* Padding to apply to top side of image as a fraction of screen height [-1..1].
*/
[Range(-1,1)]
[Tooltip("Padding to apply to top side of image as a fraction of screen height [-1..1].")]
public float top;
/**
* Padding to apply to bottom side of image as a fraction of screen height [-1..1].
*/
[Range(-1,1)]
[Tooltip("Padding to apply to bottom side of image as a fraction of screen height [-1..1].")]
public float bottom;
}
/**
* Padding offset to apply around the character image.
*/
[Tooltip("Padding offset to apply around the character image.")]
public ImagePadding imagePadding;
/**
* Scale of character image, specified as a fraction of current screen height [0..1].
*/
[Range(0, 1)]
[Tooltip("Scale of character image, specified as a fraction of current screen height [0..1].")]
public float imageScale = 0.25f;
/**
* Animation frames for multiple choice time indicator.
*/
[Tooltip("Animation frames for multiple choice time indicator.")]
public Texture2D[] timerAnimation;
/**
* Scale of timer image, specified as a fraction of current screen height [0..1].
*/
[Range(0, 1)]
[Tooltip("Scale of timer image, specified as a fraction of current screen height [0..1].")]
public float timerScale = 0.2f;
/**
* Sound effect to play when time indicator advances.
*/
[Tooltip("Sound effect to play when time indicator advances.")]
public AudioClip timerSound;
/**
* Style for dialog box background.
*/
[Tooltip("Style for dialog box background.")]
public GUIStyle boxStyle;
/**
* Style for name text.
*/
[Tooltip("Style for name text.")]
public GUIStyle nameTextStyle;
/**
* Style for say text.
*/
[Tooltip("Style for say text.")]
public GUIStyle sayTextStyle;
/**
* Style for option buttons
*/
[Tooltip("Style for option buttons.")]
public GUIStyle buttonStyle;
DialogMode dialogMode;
public DialogMode GetDialogMode()
{
return dialogMode;
}
class Option
{
public string optionText;
public Action optionAction;
public Option(string _optionText, Action _optionAction)
{
optionText = _optionText;
optionAction = _optionAction;
}
}
List<Option> options = new List<Option>();
float timeoutDuration;
Action timeoutAction;
float timeoutTimer;
int timeoutAnimationIndex;
string sayText = "";
string previousSayText = "";
string displayedSayText = "";
Action deferredAction;
Action continueAction;
float continueTimer;
bool instantCompleteText;
bool fullscreen;
// Cache scaled GUIStyle objects so we're not creating lots of new objects every frame
GUIStyle cachedBoxStyle;
GUIStyle cachedNameTextStyle;
GUIStyle cachedSayTextStyle;
GUIStyle cachedButtonStyle;
void Start()
{
if (!Application.isPlaying)
{
return;
}
CacheScaledStyles();
fullscreen = Screen.fullScreen;
}
void Update()
{
writingSpeed = Math.Max(writingSpeed, 0);
buttonsPerRow = Math.Max(buttonsPerRow, 1);
minButtonWidth = Mathf.Max(minButtonWidth, 0);
imageScale = Mathf.Max(imageScale, 0);
timerScale = Mathf.Max(timerScale, 0);
layout.size.x = Mathf.Clamp01(layout.size.x);
layout.size.y = Mathf.Clamp01(layout.size.y);
layout.offset.x = Mathf.Clamp01(layout.offset.x);
layout.offset.y = Mathf.Clamp01(layout.offset.y);
if (!Application.isPlaying)
{
return;
}
if (continueTimer > 0)
{
continueTimer -= Time.deltaTime;
continueTimer = Mathf.Max(continueTimer, 0f);
}
if (sayText.Length == 0)
{
dialogMode = DialogMode.Idle;
}
// Check if the sayText field has been modified directly.
// If that has happened, then write the text with no Action
if (sayText != previousSayText &&
sayText.Length > 0)
{
StopAllCoroutines();
Say(sayText, null);
}
if (timeoutTimer > 0)
{
timeoutTimer -= Time.deltaTime;
timeoutTimer = Mathf.Max(timeoutTimer, 0f);
}
// Update cached GUIStyles when running in editor or when switching to/from fullscreen
if (Application.isEditor ||
fullscreen != Screen.fullScreen)
{
CacheScaledStyles();
fullscreen = Screen.fullScreen;
}
}
void CacheScaledStyles()
{
cachedBoxStyle = ScaleFontSize(boxStyle);
cachedNameTextStyle = ScaleFontSize(nameTextStyle);
cachedSayTextStyle = ScaleFontSize(sayTextStyle);
cachedButtonStyle = ScaleFontSize(buttonStyle);
}
public void Say(string _sayText, Action sayAction)
{
string copyText = _sayText;
// Hack: Handle Say(""); by writing a single space character.
if (copyText.Length == 0)
{
copyText = " ";
}
continueAction = sayAction;
previousSayText = copyText;
if (timeoutDuration > 0 &&
options.Count > 0)
{
// Activate timeout timer
timeoutTimer = timeoutDuration;
}
WriteSayText(copyText);
}
void WriteSayText(string _sayText)
{
// Disable quick continue for a short period to prevent accidental taps
continueTimer = 0.4f;
instantCompleteText = false;
sayText = _sayText;
if (_sayText.Contains("<"))
{
// Hack to avoid displaying partial color tag text - write instantly
displayedSayText = _sayText;
dialogMode = DialogMode.Waiting;
}
else
{
// Use a coroutine to write the story text out over time
StartCoroutine(WriteStoryInternal());
}
}
// Coroutine to write story text out over a period of time
IEnumerator WriteStoryInternal()
{
// Zero CPS means write instantly
if (writingSpeed == 0)
{
displayedSayText = sayText;
yield break;
}
GameObject typingAudio = null;
if (writingSound != null)
{
typingAudio = new GameObject("WritingSound");
typingAudio.AddComponent<AudioSource>();
typingAudio.audio.clip = writingSound;
typingAudio.audio.loop = loopWritingSound;
typingAudio.audio.Play();
}
dialogMode = DialogMode.Writing;
displayedSayText = "";
// Make one character visible at a time
float writeDelay = (1f / (float)writingSpeed);
float timeAccumulator = 0f;
int i = 0;
while (true)
{
if (instantCompleteText)
{
instantCompleteText = false;
displayedSayText = sayText;
break;
}
timeAccumulator += Time.deltaTime;
while (timeAccumulator > writeDelay)
{
i++;
timeAccumulator -= writeDelay;
}
if (i >= sayText.Length)
{
displayedSayText = sayText;
break;
}
else
{
string left = sayText.Substring(0, i + 1);
string right = sayText.Substring(i + 1);
displayedSayText = left;
displayedSayText += "<color=#FFFFFF00>";
displayedSayText += right;
displayedSayText += "</color>";
}
yield return null;
}
dialogMode = DialogMode.Waiting;
if (typingAudio != null)
{
Destroy(typingAudio);
}
}
GUIStyle ScaleFontSize(GUIStyle style)
{
GUIStyle styleCopy = new GUIStyle(style);
styleCopy.fontSize = Mathf.RoundToInt(styleCopy.fontSize * ((float)Screen.height / 768f));
return styleCopy;
}
public void ClearOptions()
{
options.Clear();
}
public void AddOption(string optionText, Action optionAction)
{
options.Add(new Option(optionText, optionAction));
}
public void SetTimeout(float _timeoutDuration, Action _timeoutAction)
{
timeoutDuration = _timeoutDuration;
timeoutAction = _timeoutAction;
}
public void SetCharacter(string characterID)
{
for (int i = 0; i < characters.Length; ++i)
{
if (characters[i].characterID == characterID)
{
activeCharacter = i;
return;
}
}
Debug.Log ("Failed to find character ID " + characterID);
}
public virtual void OnGUI()
{
if (!Application.isPlaying ||
dialogMode == DialogMode.Idle ||
characters.Length == 0 ||
activeCharacter >= characters.Length)
{
return;
}
Rect areaRect = new Rect(layout.offset.x * Screen.width, layout.offset.y * Screen.height, Screen.width, Screen.height);
Rect sideImageRect = new Rect();
Rect dialogRect = new Rect();
// The left and right padding values are also calculated based on Screen.height to give
// consistent padding regardless of the screen aspect ratio
RectOffset imagePaddingRect = new RectOffset(Mathf.RoundToInt(imagePadding.left * Screen.height),
Mathf.RoundToInt(imagePadding.right * Screen.height),
Mathf.RoundToInt(imagePadding.top * Screen.height),
Mathf.RoundToInt(imagePadding.bottom * Screen.height));
Character character = characters[activeCharacter];
GUILayout.BeginArea(areaRect);
{
if (layout.topSpace)
{
GUILayout.FlexibleSpace();
}
GUILayout.BeginHorizontal();
{
if (layout.leftSpace)
{
GUILayout.FlexibleSpace();
}
GUILayout.BeginHorizontal(cachedBoxStyle, GUILayout.MinWidth(Screen.width * layout.size.x), GUILayout.MinHeight(Screen.height * layout.size.y));
{
if (character.imageSide == Character.ImageSide.Left &&
character.image != null)
{
// Reserve a rect for the side image based on the current screen height and imageScale
float sideImageHeight = Screen.height * imageScale;
float sideImageWidth = (sideImageHeight / character.image.height) * character.image.width;
float w = sideImageWidth + imagePaddingRect.left + imagePaddingRect.right;
float h = sideImageHeight + imagePaddingRect.top + imagePaddingRect.bottom;
sideImageRect = GUILayoutUtility.GetRect(w, h, GUILayout.Width(w), GUILayout.Height(h));
}
else if (character.imageSide == Character.ImageSide.Right)
{
DrawTimer();
}
GUILayout.BeginVertical(GUILayout.ExpandWidth(false));
{
if (character.name.Length > 0)
{
cachedNameTextStyle.normal.textColor = character.nameColor;
GUILayout.Label(new GUIContent(character.name), cachedNameTextStyle);
}
GUILayout.FlexibleSpace();
GUILayout.Label(new GUIContent(displayedSayText), cachedSayTextStyle);
GUILayout.FlexibleSpace();
// Show buttons for player options, or the continue icon if there are no options
if (options.Count > 0)
{
GUILayout.BeginHorizontal();
{
GUILayout.BeginVertical();
{
int buttonCount = 0;
for (int i = 0; i < options.Count; ++i)
{
if (buttonCount == 0)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
}
buttonCount++;
if (GUILayout.Button(options[i].optionText, cachedButtonStyle, GUILayout.MinWidth(Screen.width * minButtonWidth)))
{
AudioSource.PlayClipAtPoint(continueSound, new Vector3());
if (options[i].optionAction == null)
{
deferredAction = DoNullAction;
}
else
{
deferredAction = options[i].optionAction;
}
}
if (buttonCount == buttonsPerRow ||
i == options.Count - 1)
{
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
buttonCount = 0;
}
}
}
GUILayout.EndVertical();
}
GUILayout.EndHorizontal();
}
else if (continueIcon != null)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
Rect continueButtonRect = GUILayoutUtility.GetRect(continueIcon.width,
continueIcon.height,
GUILayout.MaxWidth(continueIcon.width),
GUILayout.MaxHeight(continueIcon.height));
if (dialogMode == DialogMode.Waiting)
{
continueButtonRect.y += Mathf.Sin(Time.timeSinceLevelLoad * 15f) * (float)(continueIcon.height * 0.2f);
GUI.DrawTexture(continueButtonRect, continueIcon);
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
GUILayout.FlexibleSpace();
}
GUILayout.EndVertical();
if (character.imageSide == Character.ImageSide.Right &&
character.image != null)
{
// Reserve a rect for the side image based on the current screen height and imageScale
float sideImageHeight = Screen.height * imageScale;
float sideImageWidth = (sideImageHeight / character.image.height) * character.image.width;
float w = sideImageWidth + imagePaddingRect.left + imagePaddingRect.right;
float h = sideImageHeight + imagePaddingRect.top + imagePaddingRect.bottom;
sideImageRect = GUILayoutUtility.GetRect(w, h, GUILayout.Width(w), GUILayout.Height(h));
}
else if (character.imageSide == Character.ImageSide.Left)
{
DrawTimer();
}
}
GUILayout.EndHorizontal();
// Get rect of dialog for testing mouse hit later on
dialogRect = GUILayoutUtility.GetLastRect();
if (layout.rightSpace)
{
GUILayout.FlexibleSpace();
}
}
GUILayout.EndHorizontal();
if (layout.bottomSpace)
{
GUILayout.FlexibleSpace();
}
}
GUILayout.EndArea();
if (character.image != null)
{
// Adjust side image rect based on aspect ratio of the image.
float sideImageHeight = character.image.height * ((sideImageRect.width - imagePaddingRect.left - imagePaddingRect.right) / character.image.width);
sideImageRect.yMax = sideImageRect.yMin + sideImageHeight + imagePaddingRect.bottom + imagePaddingRect.top;
sideImageRect = imagePaddingRect.Remove(sideImageRect);
// Adjust rect based on layout offset
sideImageRect.x += areaRect.x;
sideImageRect.y += areaRect.y;
// Draw side image
GUI.DrawTexture(sideImageRect, character.image);
}
bool clickedOnDialog = (Input.GetMouseButtonUp(0) && dialogRect.Contains(Event.current.mousePosition));
if (dialogMode == DialogMode.Writing)
{
if (clickedOnDialog || Input.GetKeyUp("space"))
{
instantCompleteText = true;
}
}
if (dialogMode == DialogMode.Waiting)
{
// Player can continue by clicking anywhere
if (options.Count == 0 &&
continueTimer == 0 &&
(clickedOnDialog || Input.GetKeyUp("space")))
{
if (continueSound != null)
{
AudioSource.PlayClipAtPoint(continueSound, new Vector3());
}
if (continueAction == null)
{
deferredAction = DoNullAction;
}
else
{
deferredAction = continueAction;
}
}
// Check if timeout timer has expired
if (options.Count > 0 &&
timeoutDuration > 0 &&
timeoutTimer == 0)
{
deferredAction = timeoutAction;
}
}
// Execute any deferred actions on the last call to OnGUI
if (Event.current.type == EventType.Repaint)
{
if (deferredAction != null)
{
Action tempAction = deferredAction;
displayedSayText = "";
sayText = "";
deferredAction = null;
dialogMode = DialogMode.Idle;
ClearOptions();
timeoutAction = null;
timeoutDuration = 0;
timeoutTimer = 0;
timeoutAnimationIndex = 0;
tempAction();
}
}
}
void DrawTimer()
{
if (timeoutTimer > 0 &&
timerAnimation.Length > 0)
{
GUILayout.BeginHorizontal();
{
GUILayout.FlexibleSpace();
GUILayout.BeginVertical();
{
GUILayout.FlexibleSpace();
float t = 1f - timeoutTimer / timeoutDuration;
int index = Mathf.RoundToInt(Mathf.Lerp(0, timerAnimation.Length - 1, t));
// Play a sound effect for each animation frame
if (timeoutAnimationIndex != index &&
timerSound != null)
{
AudioSource.PlayClipAtPoint(timerSound, Vector3.zero);
}
timeoutAnimationIndex = index;
float height = Screen.height * timerScale;
GUILayout.Box(timerAnimation[timeoutAnimationIndex], new GUIStyle(), GUILayout.Height(height));
GUILayout.FlexibleSpace();
}
GUILayout.EndVertical();
GUILayout.FlexibleSpace();
}
GUILayout.EndHorizontal();
}
}
void DoNullAction()
{}
}
}

2
Assets/Fungus/Dialog/Scripts/DialogController.cs.meta → Assets/Fungus/Legacy/Scripts/LegacyDialog.cs.meta

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 3a0bbe22c246e4c78ad8e9816cbae9d5
guid: d5fe4de5a03e34488bb65c75039a328d
MonoImporter:
serializedVersion: 2
defaultReferences: []

BIN
Assets/Shuttle/NewDialog.unity

Binary file not shown.
Loading…
Cancel
Save