|
|
|
@ -4,6 +4,7 @@ using UnityEngine.Events;
|
|
|
|
|
using System; |
|
|
|
|
using System.Collections; |
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
using System.Text.RegularExpressions; |
|
|
|
|
|
|
|
|
|
namespace Fungus.Script |
|
|
|
|
{ |
|
|
|
@ -26,6 +27,24 @@ namespace Fungus.Script
|
|
|
|
|
public Image leftImage; |
|
|
|
|
public Image rightImage; |
|
|
|
|
|
|
|
|
|
protected enum GlyphType |
|
|
|
|
{ |
|
|
|
|
Character, // Text character |
|
|
|
|
Wait, // w, w=0.5 |
|
|
|
|
WaitForInput, // i |
|
|
|
|
WaitForInputAndClear, // ic |
|
|
|
|
Clear, // c |
|
|
|
|
Speed, // s, s=60 |
|
|
|
|
Exit, // x |
|
|
|
|
Punctuation // p, p=0.5 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected class Glyph |
|
|
|
|
{ |
|
|
|
|
public GlyphType type = GlyphType.Character; |
|
|
|
|
public string param = ""; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public void ShowDialog(bool visible) |
|
|
|
|
{ |
|
|
|
|
if (dialogCanvas != null) |
|
|
|
@ -92,14 +111,30 @@ namespace Fungus.Script
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected IEnumerator WriteText(string text, Action onWritingComplete) |
|
|
|
|
protected IEnumerator WriteText(string text, Action onWritingComplete, Action onExitTag) |
|
|
|
|
{ |
|
|
|
|
// Zero CPS means write instantly |
|
|
|
|
// Also write instantly if text contains markup tags |
|
|
|
|
storyText.text = ""; |
|
|
|
|
|
|
|
|
|
List<Glyph> glyphs = MakeGlyphList(text); |
|
|
|
|
|
|
|
|
|
if (glyphs.Count == 0) |
|
|
|
|
{ |
|
|
|
|
yield break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Zero writingSpeed means write instantly |
|
|
|
|
// Also write instantly if text contains rich text markup tags |
|
|
|
|
if (writingSpeed == 0 || |
|
|
|
|
text.Contains("<")) |
|
|
|
|
{ |
|
|
|
|
storyText.text = text; |
|
|
|
|
foreach (Glyph glyph in glyphs) |
|
|
|
|
{ |
|
|
|
|
if (glyph.type == GlyphType.Character) |
|
|
|
|
{ |
|
|
|
|
storyText.text += glyph.param; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (onWritingComplete != null) |
|
|
|
|
{ |
|
|
|
|
onWritingComplete(); |
|
|
|
@ -118,32 +153,100 @@ namespace Fungus.Script
|
|
|
|
|
typingAudio.audio.Play(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
storyText.text = ""; |
|
|
|
|
float writeDelay = 0f; |
|
|
|
|
if (writingSpeed > 0) |
|
|
|
|
{ |
|
|
|
|
writeDelay = (1f / (float)writingSpeed); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Make one character visible at a time |
|
|
|
|
float writeDelay = (1f / (float)writingSpeed); |
|
|
|
|
float timeAccumulator = 0f; |
|
|
|
|
int i = 0; |
|
|
|
|
|
|
|
|
|
while (true) |
|
|
|
|
int i = 0; |
|
|
|
|
while (i < glyphs.Count) |
|
|
|
|
{ |
|
|
|
|
timeAccumulator += Time.deltaTime; |
|
|
|
|
|
|
|
|
|
while (timeAccumulator > writeDelay) |
|
|
|
|
{ |
|
|
|
|
i++; |
|
|
|
|
timeAccumulator -= writeDelay; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (i >= text.Length) |
|
|
|
|
{ |
|
|
|
|
storyText.text = text; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
string left = text.Substring(0, i + 1); |
|
|
|
|
storyText.text = left; |
|
|
|
|
Glyph glyph = glyphs[i]; |
|
|
|
|
|
|
|
|
|
switch (glyph.type) |
|
|
|
|
{ |
|
|
|
|
case GlyphType.Character: |
|
|
|
|
|
|
|
|
|
if (storyText.text.Length == 0 && glyph.param == "\n") |
|
|
|
|
{ |
|
|
|
|
// Ignore leading newlines |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
storyText.text += glyph.param; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GlyphType.Wait: |
|
|
|
|
float duration = 1f; |
|
|
|
|
if (!Single.TryParse(glyph.param, out duration)) |
|
|
|
|
{ |
|
|
|
|
duration = 1f; |
|
|
|
|
} |
|
|
|
|
yield return new WaitForSeconds(duration); |
|
|
|
|
timeAccumulator = 0f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GlyphType.WaitForInput: |
|
|
|
|
OnWaitForInputTag(true); |
|
|
|
|
yield return StartCoroutine(WaitForInput(null)); |
|
|
|
|
OnWaitForInputTag(false); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GlyphType.WaitForInputAndClear: |
|
|
|
|
OnWaitForInputTag(true); |
|
|
|
|
yield return StartCoroutine(WaitForInput(null)); |
|
|
|
|
OnWaitForInputTag(false); |
|
|
|
|
storyText.text = ""; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GlyphType.Clear: |
|
|
|
|
storyText.text = ""; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GlyphType.Speed: |
|
|
|
|
if (!Single.TryParse(glyph.param, out writingSpeed)) |
|
|
|
|
{ |
|
|
|
|
writingSpeed = 0f; |
|
|
|
|
} |
|
|
|
|
writeDelay = 0; |
|
|
|
|
if (writingSpeed > 0) |
|
|
|
|
{ |
|
|
|
|
writeDelay = (1f / (float)writingSpeed); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GlyphType.Exit: |
|
|
|
|
|
|
|
|
|
if (typingAudio != null) |
|
|
|
|
{ |
|
|
|
|
Destroy(typingAudio); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (onExitTag != null) |
|
|
|
|
{ |
|
|
|
|
onExitTag(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
yield break; |
|
|
|
|
|
|
|
|
|
case GlyphType.Punctuation: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (++i >= glyphs.Count) |
|
|
|
|
{ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
yield return null; |
|
|
|
@ -175,6 +278,137 @@ namespace Fungus.Script
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
List<Glyph> MakeGlyphList(string storyText) |
|
|
|
|
{ |
|
|
|
|
List<Glyph> glyphList = new List<Glyph>(); |
|
|
|
|
|
|
|
|
|
string pattern = @"\{.*?\}"; |
|
|
|
|
Regex myRegex = new Regex(pattern); |
|
|
|
|
|
|
|
|
|
Match m = myRegex.Match(storyText); // m is the first match |
|
|
|
|
|
|
|
|
|
int position = 0; |
|
|
|
|
while (m.Success) |
|
|
|
|
{ |
|
|
|
|
// Get bit leading up to tag |
|
|
|
|
string preText = storyText.Substring(position, m.Index - position); |
|
|
|
|
string tagText = m.Value; |
|
|
|
|
|
|
|
|
|
foreach (char c in preText) |
|
|
|
|
{ |
|
|
|
|
glyphList.Add(MakeCharacterGlyph(c.ToString())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Glyph tagGlyph = MakeTagGlyph(tagText); |
|
|
|
|
if (tagGlyph != null) |
|
|
|
|
{ |
|
|
|
|
glyphList.Add (tagGlyph); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
position = m.Index + tagText.Length; |
|
|
|
|
m = m.NextMatch(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (position < storyText.Length - 1) |
|
|
|
|
{ |
|
|
|
|
string postText = storyText.Substring(position, storyText.Length - position); |
|
|
|
|
foreach (char c in postText) |
|
|
|
|
{ |
|
|
|
|
glyphList.Add(MakeCharacterGlyph(c.ToString())); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return glyphList; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Glyph MakeCharacterGlyph(string character) |
|
|
|
|
{ |
|
|
|
|
Glyph glyph = new Glyph(); |
|
|
|
|
glyph.type = GlyphType.Character; |
|
|
|
|
glyph.param = character; |
|
|
|
|
return glyph; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Glyph MakeTagGlyph(string tagText) |
|
|
|
|
{ |
|
|
|
|
if (tagText.Length < 3 || |
|
|
|
|
tagText.Substring(0,1) != "{" || |
|
|
|
|
tagText.Substring(tagText.Length - 1,1) != "}") |
|
|
|
|
{ |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
string tag = tagText.Substring(1, tagText.Length - 2); |
|
|
|
|
|
|
|
|
|
GlyphType type = GlyphType.Character; |
|
|
|
|
string paramText = ""; |
|
|
|
|
|
|
|
|
|
if (tag == "i") |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.WaitForInput; |
|
|
|
|
} |
|
|
|
|
if (tag == "ic") |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.WaitForInputAndClear; |
|
|
|
|
} |
|
|
|
|
else if (tag.StartsWith("w=")) |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.Wait; |
|
|
|
|
paramText = tag.Substring(2, tag.Length - 2); |
|
|
|
|
} |
|
|
|
|
else if (tag == "w") |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.Wait; |
|
|
|
|
} |
|
|
|
|
else if (tag == "c") |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.Clear; |
|
|
|
|
} |
|
|
|
|
else if (tag.StartsWith("s=")) |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.Speed; |
|
|
|
|
paramText = tag.Substring(2, tag.Length - 2); |
|
|
|
|
} |
|
|
|
|
else if (tag == "s") |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.Speed; |
|
|
|
|
} |
|
|
|
|
else if (tag == "x") |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.Exit; |
|
|
|
|
} |
|
|
|
|
else if (tag.StartsWith("p=")) |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.Punctuation; |
|
|
|
|
paramText = tag.Substring(2, tag.Length - 2); |
|
|
|
|
} |
|
|
|
|
else if (tag == "p") |
|
|
|
|
{ |
|
|
|
|
type = GlyphType.Punctuation; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Glyph glyph = new Glyph(); |
|
|
|
|
glyph.type = type; |
|
|
|
|
glyph.param = paramText; |
|
|
|
|
|
|
|
|
|
return glyph; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected IEnumerator WaitForInput(Action onInput) |
|
|
|
|
{ |
|
|
|
|
while (!Input.GetMouseButtonDown(0)) |
|
|
|
|
{ |
|
|
|
|
yield return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (onInput != null) |
|
|
|
|
{ |
|
|
|
|
onInput(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected virtual void OnWaitForInputTag(bool waiting) |
|
|
|
|
{} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|