You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
4.2 KiB
211 lines
4.2 KiB
using UnityEngine; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
|
|
namespace Fungus |
|
{ |
|
public class Glyph |
|
{ |
|
public float hideTimer; |
|
public string character; |
|
public bool boldActive; |
|
public bool italicActive; |
|
public bool colorActive; |
|
public string colorText; |
|
public bool hasPunctuationPause; |
|
} |
|
|
|
public class DialogText |
|
{ |
|
protected List<Glyph> glyphs = new List<Glyph>(); |
|
|
|
public bool boldActive { get; set; } |
|
public bool italicActive { get; set; } |
|
public bool colorActive { get; set; } |
|
public string colorText { get; set; } |
|
public float writingSpeed { get; set; } |
|
public float punctuationPause { get; set; } |
|
public AudioSource typingAudio { get; set; } |
|
|
|
public virtual void Clear() |
|
{ |
|
glyphs.Clear(); |
|
} |
|
|
|
public virtual void Append(string words) |
|
{ |
|
if (typingAudio != null) |
|
{ |
|
typingAudio.Stop(); |
|
typingAudio.Play(); |
|
} |
|
|
|
float hideTimer = 0f; |
|
if (writingSpeed > 0f) |
|
{ |
|
hideTimer = 1f / writingSpeed; |
|
} |
|
|
|
bool doPunctuationPause = false; |
|
for (int i = 0; i < words.Length; ++i) |
|
{ |
|
char c = words[i]; |
|
|
|
// Ignore leading newlines |
|
if (glyphs.Count == 0 && c == '\n') |
|
{ |
|
continue; |
|
} |
|
|
|
Glyph glyph = new Glyph(); |
|
glyph.hideTimer = hideTimer; |
|
if (doPunctuationPause) |
|
{ |
|
glyph.hasPunctuationPause = true; |
|
glyph.hideTimer += punctuationPause; |
|
doPunctuationPause = false; |
|
} |
|
|
|
glyph.character = c.ToString(); |
|
glyph.boldActive = boldActive; |
|
glyph.italicActive = italicActive; |
|
glyph.colorActive = colorActive; |
|
glyph.colorText = colorText; |
|
glyphs.Add(glyph); |
|
|
|
if (i < words.Length - 1 && |
|
IsPunctuation(c)) // No punctuation pause on last character, or if next character is also punctuation |
|
{ |
|
doPunctuationPause = true; |
|
} |
|
|
|
// Special case: pause just before open parentheses |
|
if (i < words.Length - 2) |
|
{ |
|
if (words[i + 1] == '(') |
|
{ |
|
doPunctuationPause = true; |
|
} |
|
} |
|
} |
|
} |
|
|
|
protected virtual bool IsPunctuation(char character) |
|
{ |
|
return character == '.' || |
|
character == '?' || |
|
character == '!' || |
|
character == ',' || |
|
character == ':' || |
|
character == ';' || |
|
character == ')'; |
|
} |
|
|
|
/** |
|
* Returns true when all glyphs are visible. |
|
*/ |
|
public virtual bool UpdateGlyphs(bool instantComplete) |
|
{ |
|
float elapsedTime = Time.deltaTime; |
|
|
|
foreach (Glyph glyph in glyphs) |
|
{ |
|
if (instantComplete) |
|
{ |
|
glyph.hideTimer = 0f; |
|
continue; |
|
} |
|
|
|
if (glyph.hideTimer > 0f) |
|
{ |
|
if (typingAudio != null && |
|
glyph.hasPunctuationPause) |
|
{ |
|
typingAudio.volume = 0f; |
|
} |
|
|
|
bool finished = false; |
|
if (elapsedTime > glyph.hideTimer) |
|
{ |
|
elapsedTime -= glyph.hideTimer; |
|
glyph.hideTimer = 0f; |
|
// Some elapsed time left over, so carry on to next glyph |
|
} |
|
else |
|
{ |
|
glyph.hideTimer -= elapsedTime; |
|
glyph.hideTimer = Mathf.Max(glyph.hideTimer, 0f); |
|
finished = true; |
|
} |
|
|
|
// Check if we need to restore audio after a punctuation pause |
|
if (typingAudio != null && |
|
glyph.hideTimer == 0f && |
|
typingAudio.volume == 0f) |
|
{ |
|
typingAudio.volume = 1f; |
|
} |
|
|
|
if (finished) |
|
{ |
|
return false; // Glyph is still hidden |
|
} |
|
} |
|
} |
|
|
|
if (typingAudio != null) |
|
{ |
|
typingAudio.Stop(); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public virtual string GetDialogText() |
|
{ |
|
string outputText = ""; |
|
|
|
bool hideGlyphs = false; |
|
foreach (Glyph glyph in glyphs) |
|
{ |
|
// Wrap each individual character in rich text markup tags (if required) |
|
string start = ""; |
|
string end = ""; |
|
if (glyph.boldActive) |
|
{ |
|
start += "<b>"; |
|
end += "</b>"; |
|
} |
|
if (glyph.italicActive) |
|
{ |
|
start += "<i>"; |
|
end = "</i>" + end; // Have to nest tags correctly |
|
} |
|
|
|
if (!hideGlyphs && |
|
glyph.hideTimer > 0f) |
|
{ |
|
hideGlyphs = true; |
|
outputText += "<color=#FFFFFF00>"; |
|
} |
|
|
|
if (!hideGlyphs && |
|
glyph.colorActive) |
|
{ |
|
start += "<color=" + glyph.colorText + ">"; |
|
end += "</color>"; |
|
} |
|
|
|
outputText += start + glyph.character + end; |
|
} |
|
|
|
if (hideGlyphs) |
|
{ |
|
outputText += "</color>"; |
|
} |
|
|
|
return outputText; |
|
} |
|
} |
|
|
|
} |