Files
BlueRoseNote/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/UI/UI.md

8.4 KiB
Raw Blame History

title, date, excerpt, tags, rating
title date excerpt tags rating
UI 2026-05-03 00:00:00 ARC 引擎 UI/Slate/UMG 扩展合集:垂直对齐、独立透明度、文本溢出、富文本图片、几何缓存、平台本地化、简单元素着色器扩展
ARC
UI

UI — UI/Slate/UMG 扩展

返回 ARC引擎修改总览

概述

ARC 引擎对 UE4 的 UI 系统Slate + UMG进行了大量扩展主要服务于格斗游戏的文本显示需求多语言、竖排文字和控制器管理。修改涉及约 38 个文件。

控制器管理

新增 FUEISlateApplication(继承 FSlateApplication

  • User/Controller ID 映射表(UserIndexMap
  • 格斗游戏多手柄的输入分配
  • 参见 UEI事件系统

Slate 扩展

概述

ARC 引擎对 Slate 框架进行了多项扩展,主要围绕文本渲染和 Widget 性能优化。

1. 垂直文本对齐

新增 ETextJustifyV::Type 枚举,为 STextBlockSRichTextBlock 添加垂直对齐支持:

  • Top — 顶部对齐
  • Center — 垂直居中
  • Bottom — 底部对齐

格斗游戏 UI 中常需要文本在固定高度区域内垂直居中。

2. 独立阴影/描边透明度

Shadow 和 Outline 的颜色不受父 Widget 透明度影响:

标准 UE4文字透明度 50% → Shadow 也跟着变为 50%
ARC 修改:文字透明度 50% → Shadow 保持自身设定的透明度

用于格斗游戏中文字淡入淡出时保持描边清晰可见。

3. 文本溢出省略

按高度截断文本并添加省略号(...)。标准 UE4 只支持按宽度截断。

4. 富文本图片运行

SRichTextBlock 扩展了图片嵌入能力:

  • 动态 Brush 支持(运行时更换图标)
  • 范围创建(基于文本范围插入图片)

5. 几何缓存

SWidget 上新增几何缓存机制:

void SetCachedGeometry();
void UpdateGeometryAllChildren();

减少每帧的 Layout 计算开销,对格斗游戏 60fps 的帧预算至关重要。

代码修改情况

文件路径 修改类型 修改内容
Source/Runtime/Slate/Public/Widgets/Text/STextBlock.h 修改 新增 ETextJustifyV 垂直对齐属性
Source/Runtime/Slate/Private/Widgets/Text/STextBlock.cpp 修改 垂直对齐布局计算
Source/Runtime/Slate/Public/Widgets/Text/SRichTextBlock.h 修改 富文本图片运行 + 动态 Brush
Source/Runtime/Slate/Private/Widgets/Text/SRichTextBlock.cpp 修改 富文本图片运行实现
Source/Runtime/SlateCore/Public/Widgets/SWidget.h 修改 新增 SetCachedGeometryUpdateGeometryAllChildren
Source/Runtime/SlateCore/Private/Widgets/SWidget.cpp 修改 几何缓存实现
Source/Runtime/SlateCore/Private/Fonts/FontCache*.cpp 修改 文本阴影/描边独立透明度
Source/Runtime/Slate/ 其他文件 (~26个) 修改 文本溢出省略、范围创建等

UMG 本地化

概述

ARC 引擎为 UMG 文本系统添加了平台感知的本地化机制,允许同一文本 ID 在不同平台上显示不同内容(例如按钮提示文本因平台不同而变化)。

平台后缀系统

文本 ID 查找时自动追加平台后缀:

平台 后缀
PS5 _PS5
Xbox Series X _XSX
其他 无后缀(使用默认文本)

查找顺序:

  1. 先查 TextID_PS5(或 _XSX
  2. 找不到则回退到 TextID

语言 ID

新增 CVar sg_REDLanguageID,允许运行时切换语言而不依赖系统语言设置:

static TAutoConsoleVariable<int32> CVarREDLanguageID(
    TEXT("sg.REDLanguageID"),
    0,
    TEXT("Override language ID for RED localization"));

自定义 L10N 加载

Source/Runtime/Core/ 中的本地化文件加载逻辑支持自定义 L10N 目录。

兼容性

UOldRichTextBlockDecorator 兼容层确保旧版富文本格式在新系统中正常工作。

代码修改情况

文件路径 修改类型 修改内容
Source/Runtime/UMG/Private/Components/TextBlock.cpp 修改 平台后缀 _PS5/_XSX 文本查找逻辑
Source/Runtime/UMG/Public/Components/TextWidgetTypes.h 修改 垂直文本对齐支持
Source/Runtime/UMG/Private/Components/RichTextBlockDecorator.cpp 修改 UOldRichTextBlockDecorator 兼容层
Source/Runtime/UMG/Private/Components/WidgetComponent.cpp 修改 Widget 组件修改
Source/Runtime/Core/ 修改 sg_REDLanguageID CVar + 自定义 L10N 加载

简单元素渲染扩展

概述

扩展了 UE4 的 SimpleElement Pixel Shader用于 2D UI 元素、线条、Debug 绘制等),新增颜色叠加、灰度转换和 Multiply 混合模式。

新增着色器入口

REDMain / GammaREDMain

void REDMain(... out float4 OutColor : SV_Target0)
{
    OutColor = CalcREDColor(InColor, InTexCoord);
}

float4 CalcREDColor(float4 VertexColor, float2 UV)
{
    float4 TexColor = Texture2DSample(InTexture, InTextureSampler, UV);
    float4 Result = TexColor * VertexColor;

    // 叠加色
    Result.rgb += AddColor.rgb;

    // 灰度转换
    float Gray = dot(Result.rgb, float3(0.299, 0.587, 0.114));
    Result.rgb = lerp(float3(Gray, Gray, Gray), Result.rgb, Grayscale);

    return Result;
}

参数:

  • AddColor — 加法颜色叠加uniform float3
  • Grayscale — 饱和度系数uniform float0=灰度1=原色)

MainMult

Multiply 混合模式的 Simple Element 渲染:

void MainMult(... out float4 OutColor : SV_Target0)
{
    // 用于 Multiply 混合的 UI 元素
}

使用场景

  • 格斗游戏 UI 的动态颜色变化(血条变色、技能冷却灰度化)
  • 受击时的 HUD 闪烁效果AddColor 叠加红色)
  • 菜单界面的 Multiply 叠加装饰

完整代码解析

SimpleElementPixelShader.usf — RED 扩展

// ASW Change : 2013/10/01 10:08:00 Takeshi.N
// RED 扩展的 Simple Element 着色器

// 全局参数
half Grayscale;       // 饱和度控制 (0=灰度, 1=原色)
float4 AddColor;      // 加法叠加颜色

// 通用颜色计算函数
float4 CalcREDColor( float4 BaseColor, float4 VertexColor, float4 AddColor, bool bGamma )
{
    // 基色 × 顶点色 + 叠加色
    BaseColor = BaseColor * VertexColor + AddColor;

    // 可选 Gamma 校正
    if( bGamma && ( Gamma != 1.0 ) )
    {
        BaseColor.rgb = pow(saturate(BaseColor.rgb), Gamma);
    }
    
    // 灰度混合:根据 Grayscale 参数在灰度和原色之间过渡
    float luma = dot( float3( 0.299f, 0.587f, 0.114f ), BaseColor.rgb );
    return lerp( BaseColor, float4( luma.xxx, BaseColor.a ), Grayscale );
}

// 标准 RED 入口(不带 Gamma 校正)
void REDMain(..., out float4 OutColor : SV_Target0, ...)
{
    float4 BaseColor = ColourTexture2DSample(InTexture, InTextureSampler, TextureCoordinate);
    ReplicateChannelSimpleElementShader(BaseColor);
    BaseColor = CalcREDColor( BaseColor, Color, AddColor, false );
    OutColor = RETURN_COLOR( BaseColor );
}

// Gamma 校正版本
void GammaREDMain(..., out float4 OutColor : SV_Target0, ...)
{
    // 与 REDMain 相同,但 bGamma=true
    BaseColor = CalcREDColor( BaseColor, Color, AddColor, true );
    OutColor = RETURN_COLOR( BaseColor );
}

// Multiply 混合模式入口
void MainMult(..., out float4 OutColor : SV_Target0, ...)
{
    float4 BaseColor = ColourTexture2DSample(InTexture, InTextureSampler, TextureCoordinate);
    ReplicateChannelSimpleElementShader(BaseColor);
    BaseColor *= Color;
    // Premultiplied alpha multiply blend:
    // 输出 = 基色 + (1-基色) × (1-Alpha)
    // Alpha=1 时输出基色纯乘法Alpha=0 时输出白色(无效果)
    OutColor = RETURN_COLOR(BaseColor + (1.0f - BaseColor) * (1.0f - BaseColor.a));
}

代码修改情况

文件路径 行号 修改类型 修改内容
Shaders/Private/SimpleElementPixelShader.usf L432~L434 新增 GrayscaleAddColor uniform 声明
Shaders/Private/SimpleElementPixelShader.usf L436~L455 新增 CalcREDColor 通用颜色计算函数
Shaders/Private/SimpleElementPixelShader.usf L457~L487 新增 REDMain 标准 RED 入口(不带 Gamma
Shaders/Private/SimpleElementPixelShader.usf L489~L518 新增 GammaREDMain Gamma 校正版本
Shaders/Private/SimpleElementPixelShader.usf L522~L542 新增 MainMult Multiply 混合模式入口