Затухающий текст по одному символу за раз

Я разработчик игр Unity. У меня есть головоломка. У меня есть два счетчика, один из которых отображает текст по одному символу за раз, а другой принимает весь текст и постепенно исчезает:

private IEnumerator FadeTo(float aValue, float tValue)
{
    float alpha = GameText.GetComponent<Text>().color.a;
    for (float i = 0; i < 1.0f; i += Time.deltaTime / tValue)
    {
        Color alphaChange = new Color(1, 1, 1, Mathf.Lerp(alpha, aValue, i));
        GameText.GetComponent<Text>().color = alphaChange;
        yield return null;
    } 
}
private IEnumerator CharXChar(string text)
{
    for (int i = 0; i < text.Length; i++)
    {
        yield return new WaitForSeconds(0.1f);
        GameText.GetComponent<Text>().text = GameText.GetComponent<Text>().text + text[i];
    }
}

Проблема в том, что я не знаю, как заставить перечислитель FadeTo модифицировать каждый символ в отдельности. Мне нужен только шаг в правильном направлении. Любая помощь будет очень благодарна.

4 голоса | спросил Sora 31 Jam1000000amTue, 31 Jan 2017 04:39:07 +030017 2017, 04:39:07

2 ответа


2

Вот очень уродливое решение, использующее богатый текст. Он обертывает тег <color=#FFFFFF00> </color> вокруг каждой буквы, а затем обновляет альфа-значения по мере того, как затухание продвигается вдоль строки.

Я использую StringBuilder для сокращения ненужных распределений строк, но это все равно генерирует одно новое распределение каждого кадра во время работы fade (к счастью, он всегда одного размера, поэтому он не должен вызывать больших проблем).

Есть, вероятно, более эффективные варианты, такие как позиционирование второго текстового элемента для удерживания затухающих символов, но это было быстро и грязно:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

[RequireComponent(typeof(Text))]
public class TextFade : MonoBehaviour {

    [Tooltip("Number of seconds each character should take to fade up")]
    public float fadeDuration = 2f;

    [Tooltip("Speed the reveal travels along the text, in characters per second")]
    public float travelSpeed = 8f;

    // Cached reference to our Text object.
    Text _text;

    Coroutine _fade;

    // Lookup table for hex characters.
    static readonly char[] NIBBLE_TO_HEX = new char[] {
        '0', '1', '2', '3',
        '4', '5', '6', '7',
        '8', '9', 'A', 'B',
        'C', 'D', 'E', 'F'};

    // Use this for initialization
    void Start () {
        _text = GetComponent<Text>();

        // If you don't want the text to fade right away, skip this line.
        FadeTo(_text.text);
    }

    public void FadeTo(string text)
    {
         // Abort a fade in progress, if any.
         StopFade();

         // Start fading, and keep track of the coroutine so we can interrupt if needed.
         _fade = StartCoroutine(FadeText(text));
    }

    public void StopFade() { 
         if(_fade != null)
               StopCoroutine(_fade);
    }

    // Currently this expects a string of plain text,
    // and will not correctly handle rich text tags etc.
    IEnumerator FadeText(string text) {

        int length = text.Length;

        // Build a character buffer of our desired text,
        // with a rich text "color" tag around every character.
        var builder = new System.Text.StringBuilder(length * 26);    
        Color32 color = _text.color;            
        for(int i = 0; i < length; i++) {
            builder.Append("<color=#");
            builder.Append(NIBBLE_TO_HEX[color.r >> 4]);
            builder.Append(NIBBLE_TO_HEX[color.r & 0xF]);
            builder.Append(NIBBLE_TO_HEX[color.g >> 4]);
            builder.Append(NIBBLE_TO_HEX[color.g & 0xF]);
            builder.Append(NIBBLE_TO_HEX[color.b >> 4]);
            builder.Append(NIBBLE_TO_HEX[color.b & 0xF]);
            builder.Append("00>");
            builder.Append(text[i]);
            builder.Append("</color>");
        }

        // Each frame, update the alpha values along the fading frontier.
        float fadingProgress = 0f;
        int opaqueChars = -1;    
        while(opaqueChars < length - 1) { 
            yield return null;

            fadingProgress += Time.deltaTime;

            float leadingEdge = fadingProgress * travelSpeed;

            int lastChar = Mathf.Min(length - 1, Mathf.FloorToInt(leadingEdge));

            int newOpaque = opaqueChars;

            for(int i = lastChar; i > opaqueChars; i--) {
                byte fade = (byte)(255f * Mathf.Clamp01((leadingEdge - i)/(travelSpeed * fadeDuration)));
                builder[i * 26 + 14] = NIBBLE_TO_HEX[fade >> 4];
                builder[i * 26 + 15] = NIBBLE_TO_HEX[fade & 0xF];

                if (fade == 255)
                    newOpaque = Mathf.Max(newOpaque, i);
            }

            opaqueChars = newOpaque;

            // This allocates a new string.
            _text.text = builder.ToString();
        }

        // Once all the characters are opaque, 
        // ditch the unnecessary markup and end the routine.
        _text.text = text;

        // Mark the fade transition as finished.
        // This can also fire an event/message if you want to signal UI.
        _fade = null;
    }
}

Вот пример эффекта:

 Анимация, в которой текст исчезает в символе по символу.

ответил DMGregory 31 Jam1000000amTue, 31 Jan 2017 06:40:40 +030017 2017, 06:40:40
-1

Есть несколько вещей, которые вы могли бы попробовать, но не обязательно с кодом, который у вас есть сейчас, а с инструментами Unity.

Сначала вы можете попробовать добавить в холст с текстом, когда вы его добавите, оттуда вы можете напрямую изменить альфа-значение холста, которое приведет к его исчезновению /выходу. Подробнее здесь .

Вы также можете попробовать GUITextures, так как у них есть свойства fade. У них также есть доступ к цветам. Подробнее здесь .

И вот C # solution Я нашел, я только связываю этот, потому что я не могу взять на себя ответственность за это;) Кажется, он похож на ваш, поскольку он использует перечисления, но он также обновляет его с помощью ввода из клавиатуру, которую вы можете легко изменить, так что вы можете вызвать эти методы.

ответил n_palum 31 Jpm1000000pmTue, 31 Jan 2017 16:13:45 +030017 2017, 16:13:45

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132