/// <returns>A duration based on the text length and the Dialogue Manager's Subtitle Settings > Min Subtitle Seconds and Subtitle Chars Per Second.</returns> public float GetDefaultSubtitleDuration(string text) { if (overrideGetDefaultSubtitleDuration != null) { return(overrideGetDefaultSubtitleDuration(text)); } int numCharacters = string.IsNullOrEmpty(text) ? 0 : Tools.StripRichTextCodes(text).Length; return(Mathf.Max(settings.GetMinSubtitleSeconds(), numCharacters / Mathf.Max(1, settings.GetSubtitleCharsPerSecond()))); }
/// <returns> /// A duration based on the text length and the Dialogue Manager's /// Subtitle Settings > Min Subtitle Seconds and Subtitle Chars Per Second. /// Also factors in time for RPGMaker-style pause codes. /// </returns> public float GetDefaultSubtitleDuration(string text) { if (overrideGetDefaultSubtitleDuration != null) { return(overrideGetDefaultSubtitleDuration(text)); } int numCharacters = string.IsNullOrEmpty(text) ? 0 : Tools.StripRichTextCodes(text).Length; float numRPGMakerPauses = 0; if (text.Contains("\\")) { var numFullPauses = (text.Length - text.Replace("\\.", string.Empty).Length) / 2; var numQuarterPauses = (text.Length - text.Replace("\\,", string.Empty).Length) / 2; numRPGMakerPauses = (1.0f * numFullPauses) + (0.25f * numQuarterPauses); } return(Mathf.Max(settings.GetMinSubtitleSeconds(), numRPGMakerPauses + (numCharacters / Mathf.Max(1, settings.GetSubtitleCharsPerSecond())))); }
private static Sequencer PlayBarkSequence(Subtitle subtitle, Transform speaker, Transform listener) { if (!string.IsNullOrEmpty(subtitle.sequence)) { var sequence = Sequencer.ReplaceShortcuts(subtitle.sequence); if (sequence.Contains(SequencerKeywords.End)) { var text = subtitle.formattedText.text; int numCharacters = string.IsNullOrEmpty(text) ? 0 : Tools.StripRichTextCodes(text).Length; var endDuration = Mathf.Max(DialogueManager.displaySettings.GetMinSubtitleSeconds(), numCharacters / Mathf.Max(1, DialogueManager.displaySettings.GetSubtitleCharsPerSecond())); sequence = sequence.Replace(SequencerKeywords.End, endDuration.ToString(System.Globalization.CultureInfo.InvariantCulture)); } return(DialogueManager.PlaySequence(sequence, speaker, listener, false, false, subtitle.entrytag)); } else { return(null); } }
public void SpeakSubtitle(Subtitle subtitle, bool wait) { if (subtitle.speakerInfo.transform == this.transform) { var text = Tools.StripRichTextCodes(subtitle.formattedText.text); if (!string.IsNullOrEmpty(text)) { Speak(text); if (wait) { var sequencer = DialogueManager.Instance.GetComponent <Sequencer>(); if (sequencer != null) { sequencer.PlayCommand("RTVoiceWait", false, 0, null, null); } } } } }
/// <summary> /// Sets the content of the panel. Assumes the panel is already open. /// </summary> public virtual void SetContent(Subtitle subtitle) { if (subtitle == null) { return; } currentSubtitle = subtitle; if (!onlyShowNPCPortraits || subtitle.speakerInfo.isNPC) { if (portraitImage != null) { var sprite = subtitle.GetSpeakerPortrait(); portraitImage.sprite = sprite; Tools.SetGameObjectActive(portraitImage, sprite != null); } portraitName.text = subtitle.speakerInfo.Name; UITools.SendTextChangeMessage(portraitName); } TypewriterUtility.StopTyping(subtitleText); var previousText = accumulateText ? m_accumulatedText : string.Empty; var previousChars = accumulateText ? UITools.StripRPGMakerCodes(Tools.StripTextMeshProTags(Tools.StripRichTextCodes(previousText))).Length : 0; SetFormattedText(subtitleText, previousText, subtitle.formattedText); if (accumulateText) { m_accumulatedText = subtitleText.text + "\n"; } if (delayTypewriterUntilOpen && !hasFocus) { StartCoroutine(StartTypingWhenFocused(subtitleText, subtitleText.text, previousChars)); } else { TypewriterUtility.StartTyping(subtitleText, subtitleText.text, previousChars); } }
/// <summary> /// Plays the typewriter effect. /// </summary> public IEnumerator Play(int fromIndex) { if ((textComponent != null) && (charactersPerSecond > 0)) { if (waitOneFrameBeforeStarting) { yield return(null); } fromIndex = Tools.StripRichTextCodes(textComponent.text.Substring(0, fromIndex)).Length; ProcessRPGMakerCodes(); if (runtimeAudioSource != null) { runtimeAudioSource.clip = audioClip; } onBegin.Invoke(); paused = false; float delay = 1 / charactersPerSecond; float lastTime = DialogueTime.time; float elapsed = fromIndex / charactersPerSecond; textComponent.maxVisibleCharacters = fromIndex; textComponent.ForceMeshUpdate(); yield return(null); textComponent.maxVisibleCharacters = fromIndex; textComponent.ForceMeshUpdate(); TMPro.TMP_TextInfo textInfo = textComponent.textInfo; int totalVisibleCharacters = textInfo.characterCount; // Get # of Visible Character in text object charactersTyped = fromIndex; int skippedCharacters = 0; while (charactersTyped < totalVisibleCharacters) { if (!paused) { var deltaTime = DialogueTime.time - lastTime; elapsed += deltaTime; var goal = (elapsed * charactersPerSecond) - skippedCharacters; while (charactersTyped < goal) { if (rpgMakerTokens.ContainsKey(charactersTyped)) { var tokens = rpgMakerTokens[charactersTyped]; for (int i = 0; i < tokens.Count; i++) { var token = tokens[i]; switch (token) { case RPGMakerTokenType.QuarterPause: yield return(new WaitForSeconds(quarterPauseDuration)); break; case RPGMakerTokenType.FullPause: yield return(new WaitForSeconds(fullPauseDuration)); break; case RPGMakerTokenType.SkipToEnd: charactersTyped = totalVisibleCharacters - 1; break; case RPGMakerTokenType.InstantOpen: var close = false; while (!close && charactersTyped < totalVisibleCharacters) { charactersTyped++; skippedCharacters++; if (rpgMakerTokens.ContainsKey(charactersTyped) && rpgMakerTokens[charactersTyped].Contains(RPGMakerTokenType.InstantClose)) { close = true; } } break; } } } var typedCharacter = (0 <= charactersTyped && charactersTyped < textComponent.text.Length) ? textComponent.text[charactersTyped] : ' '; if (charactersTyped < totalVisibleCharacters && !IsSilentCharacter(typedCharacter)) { PlayCharacterAudio(); } onCharacter.Invoke(); charactersTyped++; textComponent.maxVisibleCharacters = charactersTyped; if (IsFullPauseCharacter(typedCharacter)) { yield return(new WaitForSeconds(fullPauseDuration)); } else if (IsQuarterPauseCharacter(typedCharacter)) { yield return(new WaitForSeconds(quarterPauseDuration)); } } } textComponent.maxVisibleCharacters = charactersTyped; HandleAutoScroll(); //---Uncomment the line below to debug: //Debug.Log(textComponent.text.Substring(0, charactersTyped).Replace("<", "[").Replace(">", "]") + " (typed=" + charactersTyped + ")"); lastTime = DialogueTime.time; var delayTime = DialogueTime.time + delay; int delaySafeguard = 0; while (DialogueTime.time < delayTime && delaySafeguard < 999) { delaySafeguard++; yield return(null); } } } Stop(); }