主题
GameUI 自定义字体
用于排查和配置 Label、Input、TextButton 等 GameUI 文本控件的自定义字体。Canvas 绘图字体是另一套 NanoVG API,见本文末尾。
先判定控件类型
Label.Font/Input.Font/TextButton.Font:传的是字体 family,不是.ttf/.otf文件路径。Canvas.CreateFont(name, filename):传的是具体字体文件路径,只影响 Canvas 绘图,不会让Label.Font自动可用。
Label/Input 字体配置流程
- 确认字体文件位置。
- 项目私有随包字体:放在
<Project>/res/font/MyFont/MyFont.ttf。 - 公共 UI 字体:资源路径通常是
ui/font/MyFont/MyFont.ttf,例如 SDK/官方资源里的ui/font/Regular/Regular.otf。
- 项目私有随包字体:放在
- 在当前地图的
<Project>/ref/fontref.txt中添加字体 family,一行一个。- 项目私有字体写
font/MyFont,不要写res/font/MyFont。 - 公共 UI 字体写
ui/font/MyFont。 - 优先写 family 目录;旧逻辑兼容写具体文件,但控件代码仍应使用目录 family。
- 项目私有字体写
- 在代码里把控件字体设置为同一个 family。
label.Font = "font/MyFont"u8;label.Font = "ui/font/MyFont"u8;
- 重启本局或重新进入地图。运行期不会为 API>=7 的游戏动态加载未在
fontref.txt中声明的字体。
常见错误
- 把
Label.Font写成font/MyFont/MyFont.ttf或绝对路径。应该写font/MyFont。 - 字体放在
<Project>/res/font/MyFont/MyFont.ttf,但 family 写成res/font/MyFont。项目res/是资源根,代码路径不包含res/。 - 只复制了字体文件,没有把 family 加到
ref/fontref.txt。 - 改了
fontref.txt后没有重新加载地图。 - 自定义字体找不到时会 fallback 到
ui/font/regular,文字仍会显示,看起来像“没生效”。检查客户端日志中的Invalid font或Can't find font family。
字体加载时机
client+wasicore 路径会在游戏初始化时读取当前地图的 ref/fontref.txt 并预加载字体 family。预加载结束后,游戏运行中不再允许动态加载新 family。因此配置必须在启动前存在。
数编 UI(GameDataControl 及其派生控件)的 Font 字段和 GameCore.ResourceType.Font 类型资源会在保存生成时自动收集到当前地图的 ref/fontref.txt,已有条目保留、重复 family 去重;res/ 前缀和具体字体文件写法会归一为 family。C# 代码里写死的 family 不会从源码推断,需要手工补行。项目私有字体只写入 fontref.txt,不进入云资源 ref/dataref.txt。
共享别名归一:Regular、MiSans、Microsoft Yahei、Custom → ui/font/Regular;SourceHanSerif、NoWarRounded、ALiMaMa、LXGWWenKai → 各自的 ui/font family。表外裸名不会自动收集,请写完整 family 路径。
支持格式
运行时字体资源支持常见 FreeType 字体和位图字体:.ttf、.otf、.woff、.woff2、.ttc、.xml、.fnt、.sdf。
Canvas 字体例外
Canvas 绘图用 NanoVG 字体接口:
csharp
#if CLIENT
var fontId = Canvas.CreateFont("MyCanvasFont", "font/MyFont/MyFont.ttf");
canvas.FontFaceId(fontId);
#endif这只注册 Canvas 绘制用字体,不等价于 Label.Font = "font/MyFont"。