objective-c - Sprite Kit 的主要 iOS9 性能问题

标签 objective-c performance sprite-kit ios9 xcode7

我在使用 iOS9 时遇到了巨大的性能问题,我不知道该怎么做。我读过很多帖子 - here , 和 here例如,但他们建议的解决方案没有帮助或几乎没有区别。

我的游戏从旧 iPad 2 (iOS 8.4) 上的 60fps 变成了新 iPad mini (iOS 9) 上的 < 15fps。

我正在努力找出罪魁祸首。我很确定其中之一是 SKCropNodes。我通常在我的场景中渲染几个 SKCropNodes (6 - 18)。这在 iOS8 中从来都不是问题,但看起来 iOS9,虽然它在裁剪方面做得更好,但这样做也会消耗性能。

如果我将裁剪节点渲染为普通的 SKSpriteNodes,我可能会在旧设备上获得 5fps,在较新的 iPhone 6 上获得最多 30 帧。除了使用裁剪节点之外,我别无选择,但这不可能是全部问题。

我认为可能使用了错误的纹理图集 - 即更大的分辨率之一。然而,强制我的设备使用一个非常小的图集并没有什么区别。

我正在使用 Texture Packer 来生成我的 map 集,其中包含适用于不同设备的缩放变体。我注意到 XCAssets 现在具有添加 Sprite Atlas 的选项(我似乎找不到任何关于此的文档)。这不适合我的游戏,因为我使用了 100 个 Sprite 。我已经尝试将我的 map 集添加到 XCAssets,但由于某种原因它不会使用缩放变体。尽管如此,使用低分辨率纹理,它仍然运行得非常糟糕。

我试过设置

skView.ignoresSiblingOrder = YES;

并给出我所有节点的 zPosition 值,但仍然没有效果。我还为每个图像名称添加了 .png 扩展名(最初是一个问题,意味着它们不会呈现。)

我的场景中有一些 SKEffectNodes,但删除和添加这些似乎没有效果。

我不明白相同的硬件和相同的代码如何产生如此截然不同的结果。显然,苹果已经改变了一些与渲染有关的东西,这产生了不利影响。他们似乎也无意解决这些问题。我知道这个问题已经存在数月了——早在 iOS9 发布之前。

我已经在这个游戏上工作了 2 年了,只是在 iOS9 之前才发布它。它现在遭受糟糕的性能和经常崩溃的困扰。

有没有人想出苹果到底做了什么来降低性能?如果我知道,我至少可以尝试解决它...谢谢。

更新

以下是同一场景的一些数字,其中包含游戏一次生成的绝对最大节点数。

iOS 8、iPad 2、~200 个节点、~100 次绘制、58.7 - 60 fps

iOS 9,iPhone6,~280 个节点,~216 次绘制,约 20 fps

我认为节点数量的差异是由于屏幕尺寸不同造成的。如果我在 iPhone 6 上更改场景以达到等效值,FPS 仍然在 24 左右。

更新 2

使用 Xcode 的模板 Sprite Kit 项目,并将飞船更改为包含飞船的 SKCropNode,在 iOS 8 上,我能够添加 100 艘飞船而不会出现帧速率问题。在 iOS 9 上,同一个项目,我可以在帧速率下降到 < 30 之前添加大约 25。

iPad2 上的 iOS 8:

enter image description here

iOS 9 iPhone 5:

enter image description here

在纹理图集的使​​用方面,正如我在评论中所说,我不能保证任何东西都会从同一个图集中绘制出来。我的游戏包含自定义角色,以及来自一系列 map 集的 Assets (每个 map 集包含约 100 个纹理)。屏幕上一次最多可以显示 9 个字符。我知道这在抽签方面并不是最有效的,但是直到 iOS9 之前我从来没有遇到过问题......

更新 3

我已经向 Apple 提交了一个错误,包括我的示例程序。我还用完了我的一项技术支持请求。到目前为止,Apple 一无所获。

最佳答案

有两个主要问题。

一个是由于各种原因,从 iOS 8 到 iOS 9,Sprite Kit 的性能急剧下降,其中一些您已经链接到,但还有其他一些原因。渲染、排序和存储/处理节点的许多方面似乎都被破坏了,或者将它们之前在 CPU/GPU 上的负载增加了一倍或三倍。

然而,还有另一个问题进一步加剧了解决任何可能的性能问题的努力。这是一种普遍且看似任意的帧速率上限机制,当它以 40fps 运行时最容易引起注意。但它也以其他频率运行。

多年来,当人们手动使用 CADisplayLink 以每帧为基础创建游戏循环或其他基于计时的机制时,这种限制已经(很少)被注意到。

在 iOS 9 中,这种看似自动的上限已成为 Sprite Kit、SceneKit、Metal 和基于 OpenGL ES 的应用程序的一个非常不需要的“功能”。

在 SceneKit 的情况下,这是最有说服力的,因为无论渲染选择如何——Metal 或 OpenGL——都会发生上限,而且似乎在所有设备上,包括新的 6S 手机和 iPad Air 2 之类的东西,即使是非常简单的默认模板项目。

“渲染器”是设备上屏幕上 SceneKit 的详细统计信息中的一个行项目。这是封顶过程最有说服力的迹象。当游戏以 60fps 稳定运行时,它就不存在了。

当上限为 40fps 时,无论在屏幕上和逻辑上执行其他事件所需的时间多长,该组件都将吸收保持稳定的 40fps 上限所需的游戏循环中的所有剩余时间。它根据其他事件所需的时间而变化,总是迫使底层操作系统的一个明显目标是将帧速率保持在 40fps。

此问题与有关 iOS 9 Sprite Kit 性能的问题相结合意味着目前可能无法解决您的所有问题。很难确定您何时达到这些(看似)任意的 fps 上限之一而不是导致实际问题。

顺便说一句,这些上限不限于 40fps。我注意到它们的速度为 30fps、24fps、20fps、15fps、12fps 和 8fps。

当然,Apple 从未承认或承认操作系统中的这种上限机制,也从未评论过它何时/如何/为什么会如此严重地影响游戏和渲染过程。

正如这篇文章 (Inconsistent SceneKit framerate) 所表达的,我的理论是,它是 iOS 的一部分,旨在促进 iPad Pro 和其他设备中即将推出的可变帧速率技术的使用。

120Hz 成为 future 设备的基本速率是有道理的,特别是考虑到 iOS 的性能优势、新的 Apple TV 和 iPad Pro 中屏幕触摸/笔的 240Hz 采样......以及相当数量的 120Hz市场上的电视机。

即使没有可变帧率技术(比如……你的电视),120Hz 显示率意味着可以以稳定的 5:5:5 帧显示模式播放 24fps 电影——这极大地增加了观看电影时的乐趣/沉浸感,几乎所有这些都被拍摄并真正利用了真正的 24fps 的优势来实现模糊和运动效果。

与目前在所有设备上使用的最大帧速率为 60fps 的下拉方法相比,具有可变帧速率技术或 5:5:5 帧显示的 120Hz 也将为 Apple 在电影压缩和解压缩方面节省大量精力。

所有猜测,但我猜想在游戏引擎技术中使用这些帧率上限也有助于降低游戏的功耗,并为(在 future )开发人员提供将其游戏帧率锁定在可变帧中的选项评价设备世界。非常不幸的是(如果是这种情况)他们做得很差,或者解决了操作系统中的上限问题和 Sprite Kit 的性质,导致你盲目地争取好,高,一致的帧率。

苹果对这两类问题所引起的问题的沉默和看似漠不关心的态度(很可能)非常强烈地表明了他们对“他们的游戏开发社区”的看法。

这是处理游戏制作所固有的各种尖端和性能关键开发问题的最大单一问题,该问题来自一个不必要的 secret 和不交流(几乎好战)的组织的闭源框架。

关于objective-c - Sprite Kit 的主要 iOS9 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33043369/

相关文章:

ios - AFNetworking 请求失败 : unacceptable content-type: text/html

ios - 如何获取返回 rgb、hex 值的图像像素? ios

performance - Haskell中的平等效率

ios - 如何立即结束声音?

ios - 如何使用 NSDictionary 并将我的字符串数组映射到每个 UIViewController 类

ios - 简单的 segue 在 xcode 7 中不起作用

multithreading - 是否有关于如何在没有 block 的情况下使用 NSOperationQueue 的教程?

c# - SQLite 写入性能

ios - 使用 Sprite 工具包制作自定义场景而不使用自动布局

ios - SpriteKit : Getting node at CGPoint