using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Events;
using UnityEngine.UI;
///
/// Author: Tim van den Bosch
///
[RequireComponent(typeof(Text))]
[RequireComponent(typeof(TextFader))]
[RequireComponent(typeof(AudioSource))]
public class TextAutoTyper : MonoBehaviour
{
#region Public variables
public bool StartTyping = true; //Immediately begin typing if this is set to true.
public bool KeepSentences = false; //Enable this if you want all sentences to be displayed, line after line.
[Serializable]
public class Sentence
{
[TextArea(3, 10)]
public string Line; //The line to be typed.
public float WaitTime = 1f; //Waiting time before the next sentence in the list.
public float CharTime = 0.5f; //The time the characters are displayed in the sentence.
}
public Sentence[] Sentences; //The sentences that need to be autotyped
public int StartSentence = 0; //The sentence that begins autotyping.
public float StartDelay = 0f; //Set the starting delay for the whole autotype sequence.
public bool UseFading = false; //Use fading when switching between sentences.
public bool LastSentenceDisapear = true; //Make the last sentence disapear or stay. Note: the OnDone will still be called.
public float LastSentenceTime = 1f; //The time before the last sentences is done.
public AudioClip CharSoundClip; //The sound for when a character in a sentence has been typed.
public UnityEvent OnDone; //Called when all the sentences are done.
#endregion
#region Private variables
private Text _DisplayText;
private bool _IsTyping;
private bool _StartDelayEnded;
private float _StartTimer;
private float _LastSentenceTimer;
private float _CharTimer;
private float _SentenceTimer;
private int _SentenceNum;
private string _CurrentSentence;
private bool _GotoNextSentence;
private TextFader _TextFader;
private AudioSource _AudioSource;
#endregion
// Use this for initialization
void Start()
{
_AudioSource = GetComponent();
if (Sentences.Length <= 0)
Debug.LogError("[TextAutotype] No sentences found on gameobject: " + gameObject.name);
ResetSentences(StartSentence);
if (StartTyping)
BeginTyping();
}
///
/// Begin the auto typing sequence.
///
public void BeginTyping()
{
_IsTyping = true;
_StartDelayEnded = false;
}
///
/// Reset the who auto typ sequence to his begin status.
///
/// with which sentence do we start
public void ResetSentences(int startSentence = 0)
{
StartSentence = Mathf.Min(Sentences.Length - 1, startSentence);
_StartTimer = 0f;
_CharTimer = 0f;
_SentenceTimer = 0f;
_DisplayText = GetComponent();
_DisplayText.text = "";
_SentenceNum = StartSentence;
_CurrentSentence = Sentences[StartSentence].Line;
_GotoNextSentence = false;
//Use the fading component if we have fading enabled.
if (UseFading)
{
_TextFader = GetComponent();
_TextFader.FadeSpeed = 0.8f;
_TextFader.StartFade = true;
}
}
///
/// Stop the auto type sequence.
///
public void StopTyping()
{
_IsTyping = false;
_StartTimer = 0f;
}
// Update is called once per frame
void Update()
{
if (_IsTyping && Sentences.Length > 0)
{
//Start the delay and make sure the starttimer doesn't keep adding up after the delay has ended.
if (!_StartDelayEnded)
{
_StartTimer += Time.deltaTime;
if (_StartTimer >= StartDelay)
{
_StartTimer = 0f;
_StartDelayEnded = true;
}
}
//Check if the start delay has ended, if so begin the autotype sequence.
else if (_StartDelayEnded)
{
if (!_GotoNextSentence)
{
_CharTimer += Time.deltaTime;
if (_CharTimer >= Sentences[_SentenceNum].CharTime)
{
//Autotype the current sentence. If done, goto the next sentence in the list.
if (AutoType(_CurrentSentence))
{
//Fade the text out if isn't the last
if (UseFading && _SentenceNum < (Sentences.Length - 1))
_TextFader.BeginFade(TextFader.FadeType.FadeOut, 1f / Sentences[_SentenceNum].WaitTime);
_GotoNextSentence = true;
}
_CharTimer = 0;
}
}
else
{
//Check if all sentences in the list are done.
if (_SentenceNum >= Sentences.Length - 1)
{
//Wait before the timer has expired. then call the OnDone event and let the last text disapear if enabled.
_LastSentenceTimer += Time.deltaTime;
if (_LastSentenceTimer >= LastSentenceTime)
{
//Let the last text disapear. Use fading if enabled.
if (LastSentenceDisapear)
{
if (UseFading)
{
_TextFader.BeginFade(TextFader.FadeType.FadeOut, 1f / _LastSentenceTimer);
_TextFader.OnComplete.AddListener(DoneTyping);
_IsTyping = false;
}
else
DoneTyping();
}
else
{
OnDone.Invoke();
_IsTyping = false;
}
}
}
else
{
//Get a new sentence, will give old sentence back until sentence time has expired.
string newSentence = GetNextSentence();
//Use the new sentence and start autotyping it.
if (newSentence != _CurrentSentence)
{
if (UseFading)
_TextFader.BeginFade(TextFader.FadeType.FadeIn);
//Put all senteces into one string sepperated by an "enter".
if (KeepSentences)
_CurrentSentence += "\n" + newSentence;
else
{
//Clean up the display text and display the next sentence.
_DisplayText.text = "";
_CurrentSentence = newSentence;
}
_CharTimer = 0;
_GotoNextSentence = false;
_SentenceTimer = 0f;
}
}
}
}
}
}
///
/// Get the next sentence in the list, after an amount of time.
///
///
private string GetNextSentence()
{
_SentenceTimer += Time.deltaTime;
if (_SentenceTimer >= Sentences[_SentenceNum].WaitTime)
{
return Sentences[++_SentenceNum].Line;
}
return _CurrentSentence;
}
///
/// Autotype the given sentence, returns true if the complete sentence has been typed.
///
///
///
/// true if the complete sentence has been typed.
private bool AutoType(string sentence)
{
if (Sentences.Length <= 0)
return false;
//Calculate which character to type, based on the left characters in the sentence.
int charNum = _DisplayText.text.Length % (sentence.Length + 1);
if (charNum < sentence.Length)
{
if (CharSoundClip != null)
_AudioSource.PlayOneShot(CharSoundClip);
_DisplayText.text += sentence[charNum];
}
return charNum == sentence.Length;
}
///
/// Hide the current text by displaying an empty text.
///
public void DoneTyping()
{
_StartTimer = 0f;
_IsTyping = false;
_DisplayText.text = "";
OnDone.Invoke();
}
}