reckfellENGINE

RichTextLabel: BBCode, пользовательский текст и эффекты

Полный пример C#: literal-текст, разрешённая ссылка, постепенный показ и собственный RichTextEffect.

На этой странице

Запустить пример

Добавьте UiSampleStyle.cs, RichTextDemo.cs и BlueGlowEffect.cs. Прикрепите RichTextDemo к корню Control, соберите и запустите F6. Ссылка меняет статус внутри примера, ползунок показывает часть текста, строка с именем сохраняет введённые теги как символы, нижняя форматированная строка использует собственный эффект.

Форматирование, ссылка и буквальный текст имени в узкой области

RichTextDemo.cs
C#
using Reckfell;

public partial class RichTextDemo : Control
{
    public RichTextLabel Info { get; private set; } = null!;
    public RichTextLabel Log { get; private set; } = null!;
    public Label Status { get; private set; } = null!;
    public int LinkCount { get; private set; }
    public BlueGlowEffect Effect { get; private set; } = null!;
    public override void _Ready()
    {
        UiSampleStyle.Prepare(this);
        var margin = new MarginContainer(); AddChild(margin); margin.SetAnchorsAndOffsetsPreset(LayoutPreset.FullRect, margin: 24);
        var column = new VBoxContainer(); margin.AddChild(column);
        Info = new RichTextLabel
        {
            BbcodeEnabled = true, FitContent = true, ScrollActive = false, Threaded = false,
            Text = "[url=docs]" + UiSampleStyle.Text("Документация", "Documentation") + "[/url]\n[b]Reckfell[/b]  [color=#668fff]C# UI[/color]",
            VisibleCharactersBehavior = TextServer.VisibleCharactersBehavior.CharsAfterShaping
        };
        column.AddChild(Info);
        Effect = new BlueGlowEffect(); Info.InstallEffect(Effect);
        Info.AppendText("\n[blueglow speed=2]" + UiSampleStyle.Text("Свой эффект", "Custom effect") + "[/blueglow]");
        var reveal = new HSlider { MinValue = 0, MaxValue = 1, Step = .01, Value = 1 }; column.AddChild(reveal);
        reveal.ValueChanged += value => SetReveal((float)value);
        Log = new RichTextLabel { BbcodeEnabled = true, SizeFlagsVertical = SizeFlags.ExpandFill, ScrollFollowing = true, Threaded = false }; column.AddChild(Log);
        Status = new Label { Text = UiSampleStyle.Text("Ссылка обрабатывается внутри примера", "The example handles its link locally") }; column.AddChild(Status);
        Info.MetaClicked += HandleMeta;
        AddName("[b]Player[/b]");
    }
    public void AddName(string text)
    {
        Log.PushColor(new Color(.4f, .6f, 1)); Log.AddText(UiSampleStyle.Text("Имя: ", "Name: ")); Log.Pop();
        Log.AddText(text); Log.Newline();
    }
    public void SetReveal(float ratio) { if (float.IsFinite(ratio)) Info.VisibleRatio = Mathf.Clamp(ratio, 0, 1); }
    private void HandleMeta(Variant data)
    {
        if (data.VariantType != Variant.Type.String || data.AsString() != "docs") return;
        LinkCount++; Status.Text = UiSampleStyle.Text("Выбрана документация", "Documentation selected");
    }
}
BlueGlowEffect.cs
C#
using Reckfell;

[Tool]
public partial class BlueGlowEffect : RichTextEffect
{
    [Export] public string bbcode { get; set; } = "blueglow";
    public int Calls { get; private set; }
    public override bool _ProcessCustomFX(CharFXTransform charFX)
    {
        Calls++;
        double speed = 2;
        if (charFX.Env.TryGetValue("speed", out Variant value) &&
            (value.VariantType == Variant.Type.Float || value.VariantType == Variant.Type.Int))
        {
            double requested = value.AsDouble();
            if (double.IsFinite(requested)) speed = System.Math.Clamp(requested, 0, 10);
        }
        Color color = charFX.Color;
        color.A *= (float)(.75 + .25 * System.Math.Cos(charFX.ElapsedTime * speed));
        color.R *= .5f; color.G *= .7f; charFX.Color = color;
        return true;
    }
}

Три способа добавления

МетодПоведение
Text при BbcodeEnabledЗаменяет содержимое и разбирает разметку
AppendTextДобавляет разметку BBCode
AddTextДобавляет обычный текст без разбора тегов
PushColor/PushFont/PushMeta и PopЗадаёт контекст для следующих добавлений; закрывайте каждый push

Имена и сообщения пользователя передавайте AddText. Конкатенация непроверенного текста в BBCode позволяет ему менять форматирование и метаданные ссылок. Если всё же нужна строковая разметка с внешними значениями, экранируйте её по правилам BBCode; не используйте HTML-экранирование как замену. GetParsedText даёт текст без разобранных тегов и подходит для получения текста из уже построенного документа, но не является универсальным валидатором/фильтром произвольного BBCode.

Ссылка не должна автоматически запускать произвольную команду или URL. MetaClicked передаёт Variant; пример принимает только строку docs. Для внешней навигации задайте явный список допустимых схем/назначений и ожидаемое действие.

Краткий справочник разметки

НазначениеОсновные теги / параметры
Начертаниеb, i, u, s, code; нужны подходящие шрифты
Цветcolor/bgcolor/fgcolor; именованный цвет или #RRGGBB/#RRGGBBAA
Шрифт и размерfont, font_size; используйте существующий ресурс и разумный размер
Абзацp, center, left, right, fill, indent; направление/язык/интервалы проверяйте на реальном тексте
Спискиul/ol; тип нумерации и bullet задают представление списка
Ссылка / подсказкаurl, hint; поведение ссылки задаёт ваш обработчик
Изображениеimg; путь, размер и вертикальное выравнивание; не рассчитывайте на автоматическую загрузку сетевого адреса
Таблицаtable с числом колонок, cell; рамки, внутренние отступы, фон и ограничения ячейки
Горизонтальная линияhr с параметрами толщины/цвета/ширины
Буквальные скобкиlb/rb внутри доверенной BBCode-строки
Встроенная анимацияpulse, wave, tornado, shake, fade, rainbow; параметры частоты/амплитуды/цвета зависят от эффекта

Правильно вкладывайте и закрывайте теги; настройки абзаца применяйте на уровне абзаца. Не считайте тег color заменой контраста, а эффект wave — изменением layout. Полные параметры и соответствующие Push-методы находятся в RichTextLabel API.

Показ, прокрутка и стоимость

VisibleRatio от 0 до 1 управляет долей символов; 1 снимает ограничение. Это не длина BBCode-строки и не .NET string.Length. В примере используется CharsAfterShaping: сокращение текста до shaping может менять переносы и лигатуры. Для сценария typewriter учитывайте графемы, перевод и письменность; число глифов не равно числу Unicode-символов.

FitContent подгоняет размер под содержимое, ScrollActive включает внутреннюю прокрутку. Выберите ограниченную область либо внешнюю прокрутку и проверьте размеры контейнеров. ScrollFollowing удобно для журнала. Threaded позволяет фоновую подготовку, но завершение/измерения требуют IsFinished/Finished; пример отключает его для предсказуемого малого документа.

Не пересобирайте большой Text через += каждый кадр: это может заново разобрать/сформировать документ. Добавляйте порциями, ограничивайте длину журнала и профилируйте таблицы, изображения, fallback-шрифты и эффекты. Каждый push/pop должен оставлять ожидаемый стек для следующей порции.

Собственный эффект

BlueGlowEffect регистрирует имя через свойство bbcode; нижний регистр — контракт поиска движка. InstallEffect вызывается до добавления тега. Env содержит разобранные аргументы; проверяйте тип и диапазон. ElapsedTime — время эффекта, а не delta. GlyphIndex — индекс глифа шрифта, не код Unicode; для связи с исходным текстом нужны Range и данные shaping. Не выполняйте файловый ввод/вывод и тяжёлую логику для каждого глифа. Tool нужен для использования эффекта редактором; запуск игрового примера проверяется отдельно.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.