1. 项目概述
在UE5的C++开发中,字符串处理和容器使用是每个开发者都必须掌握的核心技能。不同于标准C++的std库,虚幻引擎提供了一套自己的字符串类型和容器类,这些类型在内存管理、线程安全和性能优化上都针对游戏开发做了特殊处理。
我刚开始接触UE5时,经常被Text、Name和String这三种字符串类型搞得晕头转向,也不清楚TArray、TMap这些容器和std库的对应关系。经过多个项目的实战积累,今天我就来系统梳理这些基础但极其重要的数据类型,分享一些只有踩过坑才知道的使用技巧。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 字符串类型深度解析
2.1 FString:最灵活的字符串类型
FString是UE中最接近std::string的字符串类型,提供丰富的字符串操作功能。它的底层实现采用自定义的内存分配器,与UE的内存管理系统深度集成:
cpp复制FString MyString = TEXT("Hello Unreal");
FString Concatenated = MyString + TEXT(" Engine");
重要提示:所有UE字符串字面量必须用TEXT()宏包裹,确保跨平台编码一致性
FString支持几乎所有常见的字符串操作:
- 查找:Find、Contains
- 修改:Append、Insert、RemoveAt
- 格式化:FString::Printf
- 类型转换:FromInt、FromFloat
内存特点:
- 使用堆分配存储实际字符数据
- 采用写时复制(Copy-on-Write)优化
- 默认UTF-16编码(可通过宏配置)
2.2 FName:轻量级不可变字符串
FName的设计初衷是为了高效处理重复出现的字符串(如资源名称、标签等)。它的核心特点是:
cpp复制FName TextureName = TEXT("BaseColor");
FName SameName = TEXT("BaseColor"); // 指向同一内存
关键特性:
- 全局名称表存储唯一实例
- 大小写不敏感(默认转为小写存储)
- 不可修改(每次"修改"实际创建新实例)
- 极快的比较速度(直接比较索引值)
使用场景:
- 资源引用(StaticMesh'/Game/...')
- 标签系统(Actor Tags)
- 枚举名称转换
2.3 FText:本地化友好型字符串
FText是专为国际化设计的字符串类型,支持自动语言切换和格式本地化:
cpp复制FText Greeting = NSLOCTEXT("Game", "Welcome", "Hello Player");
FText Format = FText::Format(LOCTEXT("Damage", "You took {0} damage"), DamageValue);
核心优势:
- 内置本地化键值系统
- 支持复数形式、性别敏感文本
- 自动处理数字/日期格式
- 内存安全(引用计数)
最佳实践:
- UI显示文本必须使用FText
- 玩家可见内容都应支持本地化
- 避免频繁创建动态FText(性能开销)
3. 容器类详解
3.1 TArray:动态数组的最佳选择
TArray是UE中最常用的容器,功能类似std::vector但针对游戏开发做了大量优化:
cpp复制TArray<int32> Scores;
Scores.Add(100); // 添加元素
Scores[0] = 200; // 随机访问
Scores.RemoveAt(0); // 删除元素
内存布局特点:
- 连续内存存储(缓存友好)
- 可配置的扩容策略(Slack机制)
- 支持自定义内存分配器
高级用法:
cpp复制// 批量添加
Scores.Append({90, 95, 80});
// 条件删除
Scores.RemoveAll([](int32 Val){ return Val < 60; });
// 排序
Scores.Sort();
性能提示:预分配足够容量(Reserve)可避免频繁扩容
3.2 TMap:高效的哈希映射容器
TMap相当于std::unordered_map,但提供了更多游戏开发专用功能:
cpp复制TMap<FString, int32> PlayerScores;
PlayerScores.Add(TEXT("John"), 100);
int32*
