Advertisement
Guest User

TetxtArchitect.cs

a guest
Apr 22nd, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.78 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using TMPro;
  5.  
  6. public class TextArchitect
  7. {
  8.     /// <summary>A dictionary keeping tabs on all architects present in a scene. Prevents multiple architects from influencing the same text object simultaneously.</summary>
  9.     private static Dictionary<TextMeshProUGUI, TextArchitect> activeArchitects = new Dictionary<TextMeshProUGUI, TextArchitect>();
  10.  
  11.     private string preText;
  12.     private string targetText;
  13.  
  14.     public int charactersPerFrame = 1;
  15.     public float speed = 1f;
  16.  
  17.     public bool skip = false;
  18.  
  19.     public bool isConstructing { get { return buildProcess != null; } }
  20.     Coroutine buildProcess = null;
  21.  
  22.     TextMeshProUGUI tmpro;
  23.  
  24.     public TextArchitect(TextMeshProUGUI tmpro, string targetText, string preText = "", int charactersPerFrame = 1, float speed = 1f)
  25.     {
  26.         this.tmpro = tmpro;
  27.         this.targetText = targetText;
  28.         this.preText = preText;
  29.         this.charactersPerFrame = charactersPerFrame;
  30.         this.speed = Mathf.Clamp(speed, 1f, 300f);
  31.  
  32.         Initiate();
  33.     }
  34.  
  35.     public void Stop()
  36.     {
  37.         if (isConstructing)
  38.         {
  39.             DialogSystem.instance.StopCoroutine(buildProcess);
  40.         }
  41.         buildProcess = null;
  42.     }
  43.  
  44.     IEnumerator Construction()
  45.     {
  46.         int runsThisFrame = 0;
  47.  
  48.         tmpro.text = "";
  49.         tmpro.text += preText;
  50.  
  51.         tmpro.ForceMeshUpdate();
  52.         TMP_TextInfo inf = tmpro.textInfo;
  53.         int vis = inf.characterCount;
  54.  
  55.         tmpro.text += targetText;
  56.  
  57.         tmpro.ForceMeshUpdate();
  58.         inf = tmpro.textInfo;
  59.         int max = inf.characterCount;
  60.  
  61.         tmpro.maxVisibleCharacters = vis;
  62.  
  63.         //temporary cache of cpf per construction sequence.
  64.         int cpf = charactersPerFrame;
  65.  
  66.         while (vis < max)
  67.         {
  68.             //allow skipping by increasing the characters per frame and the speed of occurance.
  69.             if (skip)
  70.             {
  71.                 speed = 1;
  72.                 cpf = charactersPerFrame < 5 ? 5 : charactersPerFrame + 3;
  73.             }
  74.  
  75.             //reveal a certain number of characters per frame.
  76.             while (runsThisFrame < cpf)
  77.             {
  78.                 vis++;
  79.                 tmpro.maxVisibleCharacters = vis;
  80.                 runsThisFrame++;
  81.             }
  82.  
  83.             //wait for the next available revelation time.
  84.             runsThisFrame = 0;
  85.             yield return new WaitForSeconds(0.01f * speed);
  86.         }
  87.  
  88.         //terminate the architect and remove it from the active log of architects.
  89.         Terminate();
  90.     }
  91.  
  92.     void Initiate()
  93.     {
  94.         //check if an architect for this text object is already running. if it is, terminate it. Do not allow more than one architect to affect the same text object at once.
  95.         TextArchitect existingArchitect = null;
  96.         if (activeArchitects.TryGetValue(tmpro, out existingArchitect))
  97.             existingArchitect.Terminate();
  98.  
  99.         buildProcess = DialogSystem.instance.StartCoroutine(Construction());
  100.         activeArchitects.Add(tmpro, this);
  101.     }
  102.  
  103.     /// <summary>
  104.     /// Terminate this architect. Stops the text generation process and removes it from the cache of all active architects.
  105.     /// </summary>
  106.     public void Terminate()
  107.     {
  108.         activeArchitects.Remove(tmpro);
  109.         if (isConstructing)
  110.             DialogSystem.instance.StopCoroutine(buildProcess);
  111.         buildProcess = null;
  112.     }
  113.  
  114.     /// <summary>
  115.     /// Force the architect to finish the text right now.
  116.     /// </summary>
  117.     public void ForceFinish()
  118.     {
  119.         tmpro.maxVisibleCharacters = tmpro.text.Length;
  120.         Terminate();
  121.     }
  122.  
  123.     /// <summary>
  124.     /// Renew this architect by giving it a new target display, overriding the old one. Allows the same architect to be used multiple times rather than
  125.     /// creating a new one.
  126.     /// </summary>
  127.     /// <param name="targ">Targ.</param>
  128.     /// <param name="pre">Pre.</param>
  129.     public void Renew(string targ, string pre)
  130.     {
  131.         targetText = targ;
  132.         preText = pre;
  133.  
  134.         skip = false;
  135.  
  136.         if (isConstructing)
  137.             DialogSystem.instance.StopCoroutine(buildProcess);
  138.  
  139.         buildProcess = DialogSystem.instance.StartCoroutine(Construction());
  140.     }
  141.  
  142.     public void ShowText(string text)
  143.     {
  144.         if (isConstructing)
  145.             DialogSystem.instance.StopCoroutine(buildProcess);
  146.  
  147.         targetText = text;
  148.         tmpro.text = text;
  149.  
  150.         tmpro.maxVisibleCharacters = tmpro.text.Length;
  151.  
  152.         //update the target of the dialogue system only if this architect is being used directly by the dialogue system.
  153.         if (tmpro == DialogSystem.instance.DialogTekst)
  154.             DialogSystem.instance.targetSpeech = text;
  155.     }
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement