优化 SKLabelNode 以减少性能问题
Optimizing SKLabelNode to reduce performance issues
使用 SpriteKit 创建 RPG 让我创建了 SKLabelNode 来显示所有游戏文本。每次我的多行文本框开始自动输入使用 SKLabelNode 的输入文本时,我都会遇到性能问题(FPS 下降和游戏滞后)。当 "summoning" UI 元素时,我也看到了性能命中,例如角色统计面板(有很多 SKLabelNode 的技能等级、技能名称等)。
资深开发人员说预加载数据总是有帮助的,因此我做了以下操作(降低了性能影响但没有消除它并且文本框仍然滞后):
// Preloaded model label (private property that is initialized in the class init method).
_modelLabel = [[SKLabelNode alloc] initWithFontNamed:_fontName];
_modelLabel.fontColor = _fontColor;
_modelLabel.fontSize = _fontSize;
_modelLabel.text = @"T";
// Constantly created label.
SKLabelNode *rowText = [[SKLabelNode alloc] initWithFontNamed:self.modelLabel.fontName];
rowText.fontColor = self.modelLabel.fontColor;
rowText.fontSize = self.modelLabel.fontSize;
rowText.text = row;
...
[self addChild:rowText];
如果能在使用 SKLabelNode 时获得更多优化技巧,我将不胜感激。
以下是我迄今为止收集的提示:
仅当使用无法通过 iOS 获得的字体时才需要预加载。
要使字体实际加载,您还需要设置预加载的文本。
尝试使用您需要的所有字符预加载 SKLabelNode
。也许,SpriteKit 只将需要的字形渲染到纹理中。
// Preloaded model label (private property that is initialized in the class init method).
_modelLabel = [[SKLabelNode alloc] initWithFontNamed:_fontName];
_modelLabel.fontColor = _fontColor;
_modelLabel.fontSize = _fontSize;
_modelLabel.text = @"ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz0123456789-+=_()";
然后将模型添加到具有最小 alpha 的场景中(但不能为零,因为如果节点的 alpha 为 0,则不会绘制);尝试将该节点保留在场景中
_modelLabel.alpha = CGFLOAT_MIN;
[self addChild:_modelLabel];
如果没有帮助:
- 通过对齐
zPosition
(又名 z-index
)来组织节点。您应该禁用 ignoresSiblingOrder
以控制 zPosition
。
让你的所有 SKLabelNode
在一个 z 级别绘制。
- 切换到位图字体。编写自定义位图字体渲染器非常容易。你应该记住的唯一一件事 - 让所有字形只在纹理图集中,这样你就可以在一次绘制调用中绘制你的文本
- 使用原生标签。我不确定,这有多大帮助。如果您的 FPS 严重下降 (~5..10FPS) 这可能对您有所帮助
在我看来,您每次需要文本时都在创建新标签。如果我是你,你只创建一次标签,只需要在需要时更改文本以及隐藏你不使用的行。
您可以做的另一件事是一次在标签上填写文本,然后将其分配给 SKCropNode。然后你可以使用 SKCropNode 把字体字符带回来,这反过来会给你一个更好的滚动效果,因为你不是一次在一个字符上做。
使用 SpriteKit 创建 RPG 让我创建了 SKLabelNode 来显示所有游戏文本。每次我的多行文本框开始自动输入使用 SKLabelNode 的输入文本时,我都会遇到性能问题(FPS 下降和游戏滞后)。当 "summoning" UI 元素时,我也看到了性能命中,例如角色统计面板(有很多 SKLabelNode 的技能等级、技能名称等)。
资深开发人员说预加载数据总是有帮助的,因此我做了以下操作(降低了性能影响但没有消除它并且文本框仍然滞后):
// Preloaded model label (private property that is initialized in the class init method).
_modelLabel = [[SKLabelNode alloc] initWithFontNamed:_fontName];
_modelLabel.fontColor = _fontColor;
_modelLabel.fontSize = _fontSize;
_modelLabel.text = @"T";
// Constantly created label.
SKLabelNode *rowText = [[SKLabelNode alloc] initWithFontNamed:self.modelLabel.fontName];
rowText.fontColor = self.modelLabel.fontColor;
rowText.fontSize = self.modelLabel.fontSize;
rowText.text = row;
...
[self addChild:rowText];
如果能在使用 SKLabelNode 时获得更多优化技巧,我将不胜感激。 以下是我迄今为止收集的提示:
仅当使用无法通过 iOS 获得的字体时才需要预加载。
要使字体实际加载,您还需要设置预加载的文本。
尝试使用您需要的所有字符预加载 SKLabelNode
。也许,SpriteKit 只将需要的字形渲染到纹理中。
// Preloaded model label (private property that is initialized in the class init method).
_modelLabel = [[SKLabelNode alloc] initWithFontNamed:_fontName];
_modelLabel.fontColor = _fontColor;
_modelLabel.fontSize = _fontSize;
_modelLabel.text = @"ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz0123456789-+=_()";
然后将模型添加到具有最小 alpha 的场景中(但不能为零,因为如果节点的 alpha 为 0,则不会绘制);尝试将该节点保留在场景中
_modelLabel.alpha = CGFLOAT_MIN;
[self addChild:_modelLabel];
如果没有帮助:
- 通过对齐
zPosition
(又名z-index
)来组织节点。您应该禁用ignoresSiblingOrder
以控制zPosition
。 让你的所有SKLabelNode
在一个 z 级别绘制。 - 切换到位图字体。编写自定义位图字体渲染器非常容易。你应该记住的唯一一件事 - 让所有字形只在纹理图集中,这样你就可以在一次绘制调用中绘制你的文本
- 使用原生标签。我不确定,这有多大帮助。如果您的 FPS 严重下降 (~5..10FPS) 这可能对您有所帮助
在我看来,您每次需要文本时都在创建新标签。如果我是你,你只创建一次标签,只需要在需要时更改文本以及隐藏你不使用的行。
您可以做的另一件事是一次在标签上填写文本,然后将其分配给 SKCropNode。然后你可以使用 SKCropNode 把字体字符带回来,这反过来会给你一个更好的滚动效果,因为你不是一次在一个字符上做。