小伙伴们好呀,我将结合游戏开发场景,详细讲解 C# 的 String.Format
函数,涵盖大部分常用格式和占位符,并提供代码示例。
String.Format
一、String.Format的核心原理
String.Format
通过 占位符 {}
和 格式说明符 动态生成字符串,解决以下问题:
- 数据插入:将变量/表达式嵌入字符串。
- 格式控制:精确控制数值、日期、货币等的显示方式。
- 对齐与填充:调整文本对齐方式和填充字符。
基本语法:
string result = String.Format("模板字符串", 参数1, 参数2, ...);
// 或使用索引占位符
string result = String.Format("玩家{0}获得{1}金币!", "张三", 100);
二、常用格式说明符分类详解
1. 数值格式化
说明符 | 用途 | 示例代码 | 输出 1234.567 |
---|---|---|---|
C | 货币格式 | ("{0:C}", 1234.567) | ¥1,234.57 |
D | 十进制整数(补零) | ("{0:D5}", 123) | 00123 |
E | 科学计数法 | ("{0:E2}", 12345) | 1.23E+004 |
F | 定点数(小数位) | ("{0:F2}", 123.456) | 123.46 |
N | 千分位分隔符 | ("{0:N}", 1234567) | 1,234,567.00 |
X | 十六进制 | ("{0:X4}", 255) | 00FF |
P | 百分比 | ("{0:P1}", 0.245) | 24.5% |
游戏开发场景:
// 显示玩家金币(保留两位小数)
string goldInfo = String.Format("金币:{0:C2}", 1500.5m);
// 输出:金币:¥1,500.50
// 显示经验值进度(百分比)
string expInfo = String.Format("经验进度:{0:P0}", 0.756);
// 输出:经验进度:75%
2. 日期时间格式化
说明符 | 用途 | 示例代码 | 输出2024-08-19 14:30 |
---|---|---|---|
d | 短日期 | ("{0:d}", DateTime.Now) | 2024/8/19 |
D | 长日期 | ("{0:D}", DateTime.Now) | 2024年8月19日 |
t | 短时间 | ("{0:t}", DateTime.Now) | 14:30 |
T | 长时间 | ("{0:T}", DateTime.Now) | 14:30:00 |
f | 完整日时 | ("{0:f}", DateTime.Now) | 2024年8月19日 14:30 |
u | 通用日时 | ("{0:u}", DateTime.Now) | 2024-08-19 14:30:00Z |
游戏开发场景:
DateTime eventTime = DateTime.Now.AddDays(3);
string eventInfo = String.Format(
"活动开放时间:{0:yyyy-MM-dd HH:mm}",
eventTime);
// 输出:活动开始时间:2024-08-22 14:30
3. 字符串对齐与填充
说明符 | 用途 | 示例代码 | 输出 |
---|---|---|---|
{0,10} | 右对齐,总宽3 | ("{0,3}", "玩家") | " 玩家" |
{0,-10} | 左对齐,总宽3 | ("{0,-3}", "玩家") | "玩家 " |
{0,#.##} | 数值两位小数 | ("{0:#.##}", 123.4) | “123.4” |
{0:0000}" | 补零到4位 | ("{0:0000}", 99) | “0099” |
游戏开发场景:
// 显示排行榜名次(右对齐)
string rankInfo = String.Format("第{0,3}名:{1,-10}", 5, "战士");
// 输出:第 5名:战士
4. 自定义复合格式
通过 分号分隔的多条件格式 实现复杂逻辑:
// 根据数值正负显示不同符号
var value1 = 456.78f;
var value2 = -123.45f;
var str1 = String.Format("{0:#0.00;负数:-0.00}", value1);
var str2 = String.Format("{0:#0.00;负数:-0.00}", value2);
Debug.Log(str1); // 456.78
Debug.Log(str2); // 负数:-123.45
三、进阶用法与注意事项
1. 命名参数(C# 6.0+)
可以在字符串中直接用{变量名}的方式,注意Unity不支持这个方式
,因为Unity用的是开源版的C#,项目叫做Mono
string name = "艾希";
int level = 30;
string msg = String.Format("玩家{0}达到{level}级!", name);
// 输出:玩家艾希达到30级!
2. 性能优化
- 避免频繁拼接:大量格式化时使用
StringBuilder
。 - 预编译格式字符串:重复使用的格式字符串可缓存。
3. 异常处理
- 索引越界:确保参数数量与占位符索引匹配。
- 类型不匹配:如用
{0:D}
格式化非整数会抛出异常。
好的!让我们继续以游戏开发为背景,深入讲解C#的string.Format
函数。我将通过多个游戏开发场景,展示这个函数如何成为UI显示、日志系统和游戏逻辑的利器。
四、实战案例
1. 游戏日志生成器
public class GameLogger
{
public static string GenerateLog(string action, int value, DateTime time)
{
return String.Format(
"[{0:HH:mm:ss}] {1}:玩家{2}完成了{3}次操作。",
time, // 时间戳
action.ToUpper(), // 动作名称大写
value.ToString("N0"), // 数值千分位格式
value // 原始数值
);
}
}
// 使用示例
string log = GameLogger.GenerateLog("击杀怪物", 1500, DateTime.Now);
// 输出:[14:30:45] 击杀怪物:玩家1,500次操作。
2. 玩家状态显示
// 传统拼接方式(易错难读)
"HP:" + hp + "/" + maxHp + " MP:" + mp + "/" + maxMp;
// 使用string.Format优化版
string.Format("HP:{0}/{1} MP:{2}/{3}",
currentHP, maxHP, currentMP, maxMP);
// 添加颜色标记(Unity富文本)
string.Format("<color=#FF0000>HP:{0}/{1}</color>
<color=#0000FF>MP:{2}/{3}</color>",
currentHP, maxHP, currentMP, maxMP);
3. 经验值进度条
float progress = (float)currentExp / maxExp;
string.Format("Lv.{0} 经验: {1:P1}", playerLevel, progress);
// 输出结果示例:Lv.15 经验: 87.5%
4. 战斗飘字系统
// 暴击时显示特殊样式
string damageText = string.Format("{0}{1}{2}",
isCritical ? "<size=24>" : "",
damageValue,
isCritical ? "</size>" : "");
// 组合颜色和图标
string.Format("<color=#{0}>{1}</color> <sprite=2>",
damageType.ColorHex, damageValue);
五、避坑指南:游戏开发者常见错误
1. 索引越界(导致运行时崩溃)
// 错误示例:参数不足
string.Format("Player: {0} - Score: {1}", playerName);
// 正确做法:检查参数数量是否匹配
2. 特殊字符处理(JSON配置读取)
// 需要显示大括号时使用双写转义
// 需要双引号时前面加转义\
string.Format("{{ \"id\": {0}, \"name\": \"{1}\" }}", itemId, itemName);
3. 性能优化(高频更新场景)
static StringBuilder sb = new StringBuilder();
// 上面是一个成员变量
// 在Update中频繁调用时
sb.Clear();
sb.AppendFormat("连击数: {0} 时间: {1:F1}", comboCount, timer);
uiText.text = sb.ToString();
六、扩展应用:自定义格式化器
实现一个伤害数字的智能格式化:
public class DamageFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
return this;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg is int damage)
{
return damage switch
{
> 10000 => $"{damage / 10000}万",
> 1000 => $"{damage / 1000}k",
_ => damage.ToString()
};
}
return arg.ToString();
}
}
// 使用示例
string.Format(new DamageFormatter(), "伤害: {0}", 15000); // 输出:伤害: 1万
通过以上案例可以看出,string.Format
在游戏开发中无处不在。下次当你需要显示玩家属性、生成系统消息或制作成就提示时,记得这个强大的文本工具!
结尾
大家好,我是吖树,一个游戏开发爱好者,希望与你们在游戏道路上共同成长
从2025年4月开始,我决定开始一个漫长到看不到尽头的计划,就是整理编写一系列Unity相关技术专栏文章
尽量做到一两天更新一次,刚开始大部分专栏都是空的啦,希望多年以后能够偶遇你们
![]() | ![]() |
---|---|
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
如果你也对游戏开发感兴趣,加个关注点个赞别 -= ^ _ ^ =-