Skip to content

Instantly share code, notes, and snippets.

@yangruihan
Created July 28, 2017 08:56
Show Gist options
  • Select an option

  • Save yangruihan/eec8c76d85a5d3974b8775159bdcf325 to your computer and use it in GitHub Desktop.

Select an option

Save yangruihan/eec8c76d85a5d3974b8775159bdcf325 to your computer and use it in GitHub Desktop.
Unity弹字脚本
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UI;
public class ForeachCharUtil : MonoBehaviour
{
public enum ShowContentStatus
{
Ready,
Showing,
Pause,
Stop,
Complete,
}
struct RichTextInfo
{
public int Index;
public int Len;
public string Content;
public string LeftTag;
public string RightTag;
}
public static readonly string Pattern = @"(<.+?>)(.*?)(</.+?>)";
[SerializeField]
private float letterPauseDuration = 1f;
[SerializeField]
private bool autoStart = true;
public string WillShowContent { set; get; }
public Text ShowText;
private ShowContentStatus _status = ShowContentStatus.Ready;
public ShowContentStatus Status
{
set { _status = value; }
get { return _status; }
}
private readonly List<RichTextInfo> _textInfos = new List<RichTextInfo>();
private int _textInfoIdx = 0;
private int _willShowContentIdx = 0;
private bool _isInit = false;
private void Start()
{
if (!isActiveAndEnabled || !autoStart || _isInit) return;
Init();
if (Status == ShowContentStatus.Ready)
StartType();
}
private void OnEnable()
{
if (!autoStart) return;
Init();
if (Status == ShowContentStatus.Ready)
StartType();
_isInit = true;
}
/// <summary>
/// 开始显示
/// </summary>
public void StartType()
{
if (ShowText == null)
return;
Init();
Status = ShowContentStatus.Showing;
StartCoroutine(TypeText());
}
/// <summary>
/// 停止显示
/// </summary>
public void StopType()
{
if (ShowText == null)
return;
ShowText.text = "";
Status = ShowContentStatus.Stop;
ResetStatus();
}
/// <summary>
/// 暂停显示
/// </summary>
public void PauseType()
{
if (ShowText == null && Status != ShowContentStatus.Showing)
return;
Status = ShowContentStatus.Pause;
}
/// <summary>
/// 继续显示
/// </summary>
public void ResumeType()
{
if (ShowText == null && Status != ShowContentStatus.Pause)
return;
Status = ShowContentStatus.Showing;
StartCoroutine(TypeText());
}
/// <summary>
/// 显示所有内容
/// </summary>
public void ShowAllContent()
{
Status = ShowContentStatus.Complete;
ShowText.text = WillShowContent;
}
private void Init()
{
if (ShowText == null)
{
Debug.LogError("没有找到绑定的Text组件");
return;
}
if (string.IsNullOrEmpty(WillShowContent))
WillShowContent = ShowText.text;
ResetStatus();
_textInfos.Clear();
foreach (Match match in Regex.Matches(WillShowContent, Pattern))
{
RichTextInfo text = new RichTextInfo();
text.Index = match.Index;
text.Len = match.Length;
text.LeftTag = match.Groups[1].Value;
text.Content = match.Groups[2].Value;
text.RightTag = match.Groups[3].Value;
_textInfos.Add(text);
}
}
private void ResetStatus()
{
ShowText.text = "";
_willShowContentIdx = 0;
_textInfoIdx = 0;
}
private IEnumerator TypeText()
{
while (_willShowContentIdx < WillShowContent.Length)
{
if (Status != ShowContentStatus.Showing)
yield break;
if (_textInfoIdx < _textInfos.Count)
{
var info = _textInfos[_textInfoIdx];
if (_willShowContentIdx >= info.Index && _willShowContentIdx < info.Index + info.Len)
{
if (Status == ShowContentStatus.Showing)
{
if (_willShowContentIdx < info.Index + info.LeftTag.Length)
_willShowContentIdx += info.LeftTag.Length;
var ch = info.LeftTag + WillShowContent[_willShowContentIdx] + info.RightTag;
ShowText.text += ch;
_willShowContentIdx++;
if (_willShowContentIdx >= info.Index + info.LeftTag.Length + info.Content.Length)
{
_willShowContentIdx += info.RightTag.Length;
_textInfoIdx++;
}
yield return new WaitForSeconds(letterPauseDuration);
}
continue;
}
}
if (Status == ShowContentStatus.Showing)
{
var ch = WillShowContent[_willShowContentIdx++];
ShowText.text += ch;
}
yield return new WaitForSeconds(letterPauseDuration);
}
Status = ShowContentStatus.Complete;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment