/// <summary> /// A coroutine that fades a <see cref="CanvasGroup"/> object's /// opacity from <paramref name="from"/> to <paramref name="to"/> /// over the course of <see cref="fadeTime"/> seconds, and then /// invokes <paramref name="onComplete"/>. /// </summary> /// <param name="from">The opacity value to start fading from, /// ranging from 0 to 1.</param> /// <param name="to">The opacity value to end fading at, ranging /// from 0 to 1.</param> /// <param name="onComplete">A delegate to invoke after fading is /// complete.</param> public static IEnumerator FadeAlpha(CanvasGroup canvasGroup, float from, float to, float fadeTime, PresentationFlag presented = null, Action onComplete = null) { canvasGroup.alpha = from; var timeElapsed = 0f; while (timeElapsed < fadeTime) { var fraction = timeElapsed / fadeTime; timeElapsed += Time.deltaTime; float a = Mathf.Lerp(from, to, fraction); canvasGroup.alpha = a; yield return(null); } canvasGroup.alpha = to; if (to == 0) { canvasGroup.interactable = false; canvasGroup.blocksRaycasts = false; } else { canvasGroup.interactable = true; canvasGroup.blocksRaycasts = true; } presented?.Set(); onComplete?.Invoke(); }
public static IEnumerator Typewriter(TextMeshProUGUI text, float lettersPerSecond, PresentationFlag presented, Action onCharacterTyped, Action onComplete) { // Start with everything invisible text.maxVisibleCharacters = 0; // Wait a single frame to let the text component process its // content, otherwise text.textInfo.characterCount won't be // accurate yield return(null); // How many visible characters are present in the text? var characterCount = text.textInfo.characterCount; // Early out if letter speed is zero or text length is zero if (lettersPerSecond <= 0 || characterCount == 0) { // Show everything and invoke the completion handler text.maxVisibleCharacters = characterCount; onComplete?.Invoke(); yield break; } // Convert 'letters per second' into its inverse float secondsPerLetter = 1.0f / lettersPerSecond; // If lettersPerSecond is larger than the average framerate, we // need to show more than one letter per frame, so simply // adding 1 letter every secondsPerLetter won't be good enough // (we'd cap out at 1 letter per frame, which could be slower // than the user requested.) // // Instead, we'll accumulate time every frame, and display as // many letters in that frame as we need to in order to achieve // the requested speed. var accumulator = Time.deltaTime; while (text.maxVisibleCharacters < characterCount) { // We need to show as many letters as we have accumulated // time for. while (accumulator >= secondsPerLetter) { text.maxVisibleCharacters += 1; onCharacterTyped?.Invoke(); accumulator -= secondsPerLetter; } accumulator += Time.deltaTime; yield return(null); } // We either finished displaying everything, or were // interrupted. Either way, display everything now. text.maxVisibleCharacters = characterCount; presented?.Set(); // Wrap up by invoking our completion handler. onComplete?.Invoke(); }
public void Start() { canvasGroup.alpha = 0; hasPresented = new PresentationFlag(); hasPresented.Clear(); }