using System; using System.Collections; using System.Reflection; using System.Text.RegularExpressions; using TMPro; using UnityEngine; public class BattleBubbleChatbox : MonoBehaviour { public Transform TextboxObject; public TextMeshPro TextUI; public AudioSource TextVoiceEmitter; private string CurrentText = ""; public int CurrentTextIndex; public int CurrentAdditionalTextIndex; private int Text_SubtractedRichText; private int StoredAfterIndex; public int PauseCounter; public CHATBOXTEXT storedchatboxtext; public CHATBOXTEXT previouschatboxtext; public bool ChatIsCurrentlyRunning; public TMP_FontAsset DefaultFont; public TMP_FontAsset DyslexicFont; public AudioClip DefaultSpeakSound; private float CurrentTextSpeedMultiplier; public bool FinishedShowingText; private string FormatCurrentText(string TargetText, bool IncludeBulletPoint, bool ActivateNextDialogueCharacter) { string text = TargetText.Replace("#", "").Replace("@", "").Replace(";", "\n") .Replace("~", "\n"); if (text.Contains('£') && ActivateNextDialogueCharacter) { if (storedchatboxtext != null && storedchatboxtext.Textboxes[StoredAfterIndex] != null && CurrentTextIndex + 1 != storedchatboxtext.Textboxes[StoredAfterIndex].Text.Length) { CurrentTextIndex++; RunText(storedchatboxtext, CurrentTextIndex, StoredAfterIndex); } else { EndText(); } } return text.Replace("£", ""); } private void FinishCurrentText() { FinishedShowingText = true; TextUI.text = FormatCurrentText(CurrentText, IncludeBulletPoint: true, ActivateNextDialogueCharacter: true); Text_SubtractedRichText = CountRichTextTagCharacters(TextUI.text); TextUI.maxVisibleCharacters = TextUI.text.Length - Text_SubtractedRichText; } public void RunText(CHATBOXTEXT Chatbox, int textindex, int additionalindex) { StopCoroutine("PlayText"); ChatIsCurrentlyRunning = true; CurrentTextIndex = textindex; CurrentAdditionalTextIndex = additionalindex; CurrentTextSpeedMultiplier = 1f; TextUI.color = Color.black; Text_SubtractedRichText = 0; FinishedShowingText = false; if (Chatbox.Textboxes[additionalindex].Character.Length != 0 && Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex] == null) { TextUI.color = Color.black; } else { CurrentTextSpeedMultiplier = Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].TextSpeedMultiplier; if (Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].TextColor == Color.white) { TextUI.color = Color.black; } else { TextUI.color = Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].TextColor; } } if (Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex] == null || Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].CharacterSound == null) { TextVoiceEmitter.clip = DefaultSpeakSound; } else { TextVoiceEmitter.clip = Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].CharacterSound; } TextUI.enabled = true; TextUI.text = ""; StoredAfterIndex = additionalindex; storedchatboxtext = Chatbox; if (PlayerPrefs.GetInt("Setting_DyslexicText", 0) == 1) { TextUI.font = DyslexicFont; } else if (PlayerPrefs.GetInt("Setting_NoFont", 0) == 0) { if (Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex] != null && Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].CharacterFont != null) { TextUI.font = Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].CharacterFont; } else { TextUI.font = DefaultFont; } } else { TextUI.font = DefaultFont; } if (Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex] != null && Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].CharacterFontSize != 0f) { TextUI.fontSize = Chatbox.Textboxes[additionalindex].Character[CurrentTextIndex].CharacterFontSize; } else { TextUI.fontSize = 64f; } StartCoroutine("PlayText"); } private void AttemptRunActions() { Debug.Log("AttemptRunActions started."); if (storedchatboxtext.Textboxes == null) { Debug.LogError("storedchatboxtext.Textboxes is null"); return; } if (storedchatboxtext.Textboxes[CurrentAdditionalTextIndex] == null) { Debug.LogError("storedchatboxtext.Textboxes[CurrentAdditionalTextIndex] is null"); return; } Textbox textbox = storedchatboxtext.Textboxes[CurrentAdditionalTextIndex]; if (textbox.Action == null) { Debug.LogError("currentTextbox.Action is null"); return; } if (textbox.Action.Length == 0) { Debug.Log("currentTextbox.Action.Length is 0"); return; } if (textbox.Action[CurrentTextIndex] == null) { Debug.Log("currentTextbox.Action[CurrentTextIndex] is null"); return; } CHATBOXACTION cHATBOXACTION = textbox.Action[CurrentTextIndex]; if (!cHATBOXACTION.RunActionOnChatEnd) { Debug.Log("action.RunActionOnChatEnd is false"); return; } Debug.Log("Action will be run: " + cHATBOXACTION.ToString()); if (cHATBOXACTION.PlaySound) { if (cHATBOXACTION.PossibleSounds == null) { Debug.LogError("action.PossibleSounds is null"); return; } if (cHATBOXACTION.PossibleSounds.Length == 0) { Debug.LogError("action.PossibleSounds.Length is 0"); return; } AudioClip audioClip = cHATBOXACTION.PossibleSounds[UnityEngine.Random.Range(0, cHATBOXACTION.PossibleSounds.Length)]; Debug.Log("Playing sound: " + audioClip.name); TextVoiceEmitter.PlayOneShot(audioClip); } if (cHATBOXACTION.RunComponentFunction) { if (cHATBOXACTION.TargetComponentGameObjectName == null) { Debug.LogError("action.TargetComponentGameObjectName is null"); return; } GameObject gameObject = GameObject.Find(cHATBOXACTION.TargetComponentGameObjectName); if (gameObject == null) { Debug.LogError("TargetGameObject not found: " + cHATBOXACTION.TargetComponentGameObjectName); return; } if (cHATBOXACTION.FunctionName == null) { Debug.LogError("action.FunctionName is null"); return; } string targetComponentClassname = cHATBOXACTION.TargetComponentClassname; if (targetComponentClassname == null) { Debug.LogError("action.TargetComponentClassname is null"); return; } Component component = gameObject.GetComponent(targetComponentClassname); if (component == null) { Debug.LogError("Couldn't find Component named: " + targetComponentClassname); return; } MethodInfo method = component.GetType().GetMethod(cHATBOXACTION.FunctionName); if (method == null) { Debug.LogError("Method not found: " + cHATBOXACTION.FunctionName); return; } Debug.Log("Invoking method: " + cHATBOXACTION.FunctionName); method.Invoke(component, null); } Debug.Log("AttemptRunActions ended."); } private void AttemptRunSubActions(bool IsChatEnd = false) { if (storedchatboxtext == null) { return; } if (storedchatboxtext.Textboxes[CurrentAdditionalTextIndex] == null) { Debug.LogError("storedchatboxtext.Textboxes[CurrentAdditionalTextIndex] is null"); return; } Textbox textbox = storedchatboxtext.Textboxes[CurrentAdditionalTextIndex]; if (textbox.Action == null) { Debug.LogError("currentTextbox.Action is null"); return; } if (textbox.Action.Length == 0) { Debug.Log("currentTextbox.Action.Length is 0"); return; } if (textbox.Action[CurrentTextIndex] == null) { Debug.Log("currentTextbox.Action[CurrentTextIndex] is null"); return; } CHATBOXACTION obj = textbox.Action[CurrentTextIndex]; CHATBOXACTION_SubAction[] subActions = obj.SubActions; if (obj.RunComponentFunction && subActions != null && subActions.Length != 0) { CHATBOXACTION_SubAction[] array = subActions; foreach (CHATBOXACTION_SubAction cHATBOXACTION_SubAction in array) { if (cHATBOXACTION_SubAction.RunActionOnChatEnd != IsChatEnd) { return; } if (cHATBOXACTION_SubAction.TargetComponentGameObjectName == null) { Debug.LogError("action.TargetComponentGameObjectName is null"); return; } GameObject gameObject = GameObject.Find(cHATBOXACTION_SubAction.TargetComponentGameObjectName); if (gameObject == null) { Debug.LogError("TargetGameObject not found: " + cHATBOXACTION_SubAction.TargetComponentGameObjectName); return; } if (cHATBOXACTION_SubAction.FunctionName == null) { Debug.LogError("action.FunctionName is null"); return; } string targetComponentClassname = cHATBOXACTION_SubAction.TargetComponentClassname; if (targetComponentClassname == null) { Debug.LogError("action.TargetComponentClassname is null"); return; } Component component = gameObject.GetComponent(targetComponentClassname); if (component == null) { Debug.LogError("Couldn't find Component named: " + targetComponentClassname); return; } MethodInfo method = component.GetType().GetMethod(cHATBOXACTION_SubAction.FunctionName); if (method == null) { Debug.LogError("Method not found: " + cHATBOXACTION_SubAction.FunctionName); return; } Debug.Log("Invoking method: " + cHATBOXACTION_SubAction.FunctionName); method.Invoke(component, null); } } Debug.Log("AttemptRunActions ended."); } public void EndText() { previouschatboxtext = storedchatboxtext; TextUI.enabled = false; StoredAfterIndex = 0; storedchatboxtext = null; CurrentText = ""; TextUI.text = ""; PauseCounter = 0; Text_SubtractedRichText = 0; CurrentTextIndex = 0; CurrentAdditionalTextIndex = 0; StopCoroutine("PlayText"); ChatIsCurrentlyRunning = false; } private void OnDestroy() { if (storedchatboxtext != null && storedchatboxtext.Textboxes[CurrentAdditionalTextIndex] != null && storedchatboxtext.Textboxes[CurrentAdditionalTextIndex].Action.Length != 0 && storedchatboxtext.Textboxes[CurrentAdditionalTextIndex].Action[CurrentTextIndex] != null && storedchatboxtext.Textboxes[CurrentAdditionalTextIndex].Action[CurrentTextIndex].RunActionOnChatEnd) { AttemptRunActions(); } AttemptRunSubActions(IsChatEnd: true); } private IEnumerator PlayText() { string StoredText = storedchatboxtext.Textboxes[CurrentAdditionalTextIndex].Text[CurrentTextIndex]; TextUI.text = StoredText; CurrentText = StoredText; TextUI.maxVisibleCharacters = 0; int MaxVisibleCharacters = 0; Text_SubtractedRichText = 0; bool ForcedFinishText = false; int messageCharLength = StoredText.Length; char[] messageCharacters = StoredText.ToCharArray(); if (storedchatboxtext != null && storedchatboxtext.Textboxes[CurrentAdditionalTextIndex] != null && storedchatboxtext.Textboxes[CurrentAdditionalTextIndex].Action.Length != 0 && storedchatboxtext.Textboxes[CurrentAdditionalTextIndex].Action[CurrentTextIndex] != null && !storedchatboxtext.Textboxes[CurrentAdditionalTextIndex].Action[CurrentTextIndex].RunActionOnChatEnd) { CHATBOXACTION cHATBOXACTION = storedchatboxtext.Textboxes[CurrentAdditionalTextIndex].Action[CurrentTextIndex]; if (cHATBOXACTION.PlaySound && cHATBOXACTION.PossibleSounds.Length != 0) { AudioClip clip = cHATBOXACTION.PossibleSounds[UnityEngine.Random.Range(0, cHATBOXACTION.PossibleSounds.Length)]; TextVoiceEmitter.PlayOneShot(clip); } GameObject gameObject = GameObject.Find(cHATBOXACTION.TargetComponentGameObjectName); if (cHATBOXACTION.RunComponentFunction && gameObject != null && cHATBOXACTION.FunctionName != null) { string targetComponentClassname = cHATBOXACTION.TargetComponentClassname; Component component = gameObject.GetComponent(targetComponentClassname); if (component != null) { if (component.GetType().GetMethod(cHATBOXACTION.FunctionName) != null) { component.GetType().GetMethod(cHATBOXACTION.FunctionName).Invoke(component, null); } else { MonoBehaviour.print("did you forget to make the method public?"); } } else { MonoBehaviour.print("Couldn't find Component named: " + targetComponentClassname); } } } AttemptRunSubActions(); while (MaxVisibleCharacters < messageCharLength) { if (messageCharacters[MaxVisibleCharacters].ToString() == " ") { MaxVisibleCharacters++; yield return new WaitForSeconds(0.0265f * CurrentTextSpeedMultiplier); } else if (StoredText[MaxVisibleCharacters] == '<') { int num = MaxVisibleCharacters; int num2 = StoredText.IndexOf('>', num); if (num2 != -1) { int num3 = num2 - num + 1; MaxVisibleCharacters += num3; Text_SubtractedRichText += num3; } } else if (messageCharacters[MaxVisibleCharacters].ToString() == "(") { MaxVisibleCharacters++; yield return new WaitForSeconds(0.0265f * CurrentTextSpeedMultiplier); } else if (messageCharacters[MaxVisibleCharacters].ToString() == ")") { MaxVisibleCharacters++; yield return new WaitForSeconds(0.0265f * CurrentTextSpeedMultiplier); } else if (StoredText[MaxVisibleCharacters].ToString() == "@") { StoredText = RemoveSelectedCharacter(StoredText, MaxVisibleCharacters); TextUI.text = StoredText; CurrentText = StoredText; messageCharLength = StoredText.Length; yield return new WaitForSeconds(0.125f * CurrentTextSpeedMultiplier); } else if (StoredText[MaxVisibleCharacters].ToString() == "#") { StoredText = RemoveSelectedCharacter(StoredText, MaxVisibleCharacters); TextUI.text = StoredText; CurrentText = StoredText; messageCharLength = StoredText.Length; yield return new WaitForSeconds(0.5f * CurrentTextSpeedMultiplier); } else if (StoredText[MaxVisibleCharacters].ToString() == ";") { StoredText = RemoveSelectedCharacter(StoredText, MaxVisibleCharacters); StoredText = AddSelectedCharacter(StoredText, MaxVisibleCharacters, "\n"); TextUI.text = StoredText; CurrentText = StoredText; messageCharLength = StoredText.Length; MaxVisibleCharacters++; yield return new WaitForSeconds(0.2f * CurrentTextSpeedMultiplier); } else if (StoredText[MaxVisibleCharacters].ToString() == "~") { StoredText = RemoveSelectedCharacter(StoredText, MaxVisibleCharacters); StoredText = AddSelectedCharacter(StoredText, MaxVisibleCharacters, "\n"); TextUI.text = StoredText; CurrentText = StoredText; messageCharLength = StoredText.Length; MaxVisibleCharacters++; yield return new WaitForSeconds(0.2f * CurrentTextSpeedMultiplier); } else if (StoredText[MaxVisibleCharacters].ToString() == ",") { MaxVisibleCharacters++; yield return new WaitForSeconds(0.0265f * CurrentTextSpeedMultiplier); } else if (StoredText[MaxVisibleCharacters].ToString() == ".") { MaxVisibleCharacters++; yield return new WaitForSeconds(0.0265f * CurrentTextSpeedMultiplier); } else if (StoredText[MaxVisibleCharacters].ToString() == "&") { StoredText = RemoveSelectedCharacter(StoredText, MaxVisibleCharacters); StoredText = AddSelectedCharacter(StoredText, MaxVisibleCharacters, Environment.UserName.ToUpper()); TextUI.text = StoredText; CurrentText = StoredText; messageCharLength = StoredText.Length; messageCharacters = StoredText.ToCharArray(); yield return new WaitForSeconds(0f); } else if (StoredText[MaxVisibleCharacters].ToString() == "£") { CurrentText = ""; TextUI.text = ""; MaxVisibleCharacters = 0; TextUI.maxVisibleCharacters = 0; CurrentTextIndex++; StopCoroutine("PlayText"); if (CurrentTextIndex + 1 < storedchatboxtext.Textboxes[StoredAfterIndex].Text.Length) { RunText(storedchatboxtext, CurrentTextIndex, StoredAfterIndex); } else { EndText(); } } else if (!ForcedFinishText) { MaxVisibleCharacters++; TextVoiceEmitter.PlayOneShot(TextVoiceEmitter.clip); yield return new WaitForSeconds(0.0265f * CurrentTextSpeedMultiplier); } else { MaxVisibleCharacters++; } TextUI.maxVisibleCharacters = MaxVisibleCharacters - Text_SubtractedRichText; } FinishedShowingText = true; } private string RemoveSelectedCharacter(string text, int Index) { return text.Remove(Index, 1); } private string AddSelectedCharacter(string text, int Index, string Insert) { return text.Insert(Index, Insert); } public int CountOfStringInText(string TargetText, char Counter) { int num = 0; bool flag = false; char[] array = TargetText.ToCharArray(); for (int i = 0; i < array.Length; i++) { if (array[i] == Counter) { flag = true; } else if (false) { num++; } } return num; } public static string RemoveRichTextTags(string input) { string pattern = "<.*?>"; return Regex.Replace(input, pattern, ""); } public int CountRichTextTagCharacters(string input) { string pattern = "<.*?>"; MatchCollection matchCollection = Regex.Matches(input, pattern); int num = 0; foreach (Match item in matchCollection) { num += item.Length; } return num; } }