我在场景中遇到巨大的FPS下降,其中有一些静态SKSpriteNode
节点,这些节点的主体定义为SKPhysicsBody
init(polygonFrom: CGPath)
以及一些简单的动态SKSpriteNode
节点使用init(rectangleOf: CGSize)
定义的实体。
动态节点在场景中触发并最终休息,具体取决于物理特性。每个动态节点都与其他动态节点冲突,也与之前提到的静态节点冲突。
游戏以60fps平稳运行,直到屏幕上的动态节点数量约为30或更多。之后,FPS开始大幅下降到10fps左右。
注1 :iOS 10上没有问题,仅限iOS 9 (我没有测试iOS 8,因为我不支持它)。< / p>
注意2 :由于动态节点数量增加,绘制调用不会增加,因此OpenGL方面似乎没有问题。
注意3 :我已禁用contactTestBitMask
以确保这不是问题的原因。
我使用 Time Profiler 运行了Instruments,专注于FPS下降的段,发现了以下奇怪的事情:
奇怪的是,在有问题的细分中超过50%的时间用于PhysicsKit
。请注意,此时是否发生碰撞或者动态节点是否只是放置在原位并不重要。结果总是一样的。
这必须是它的原因,但由于所有这些都发生在系统库(PhysicsKit
)中,我真的不知道在我的代码库中查找问题的位置。
感谢您的帮助!
答案 0 :(得分:2)
没有办法解决你的问题,因为nateslager已经提到了明显的问题,我只是告诉你一个解决方案。
你所做的是你将场景分成象限或更多,并且有某种重叠,你为这些象限保留categoryBitMask
,因为物理对象可以有多个categoryBitMask。现在你需要每帧更新这些类别,所以我想覆盖position属性并添加didSet
来告诉节点他们所在的象限。
现在这可能变得非常复杂,具体取决于你如何使用这些标志,因为你不能做像quadrant4&amp;不好,因为那时它仍会记录好坏。相反,您需要quadrant4bad作为1类。我们的想法是减少所有机构之间的检查次数。
E.G。 我们有一个场景是(-5,-5)到(5,5),大小为(11,11)
quadrant1是(-5,0),(0,0),( - 5,-5),(0,-5)
象限2是(0,0),(5,0),(0,-5),(5,-5)
象限3是(-5,5),(0,5),( - 5,0),(0,0)
象限4是(5,0),(5,5),(0,0),(5,0)
quadrantC为(-2.5,2.5),(2.5,2.5),( - 2.5, - 2.5),(2.5,2.5)
enum PhysicsCategory : UInt
{
case good = 0b1
case quadrant1Bad = 0b10
case quadrant2Bad = 0b100
case quadrant3Bad = 0b1000
case quadrant4Bad = 0b10000
case quadrantCBad = 0b100000
}
//we set up a good player at position 0,0 so he is in the center quadrant
good.contactBitMask = quadrantC
//we set up a enemy at position -5, -5 so he is in the first quadrant
bad1.contactBitMask = quadrant1
//we set up a enemy at position 5, -5 so he is in the second quadrant
bad2.contactBitMask = quadrant2
//we set up a enemy at position -5, 5 so he is in the third quadrant
bad3.contactBitMask = quadrant3
//we set up a enemy at position 5, 5 so he is in the fourth quadrant
bad4.contactBitMask = quadrant4
//we set up a enemy at position -2.5, 2.5 so he is in the third quadrant and center quadrant (remember, they have a width and height to them, so they will be in more than 1 quadrant
badC.contactBitMask = quadrant3 | quadrantC
现在我们的游戏正在运行时,只会检查其象限中的敌人,所以只能在quadrantC上进行检查
如果good进入quadrant3,那么只会进行2次检查,bad3和badC
这将有助于减少物理学后端的调用,这样可以减少滞后。
如果您碰巧使用了很多不同的类别,那么我建议您不要使用多个位掩码,当敌人不在某个象限时关闭敌人的categoryBitMasks。这也将减少物理引擎完成的检查次数。
答案 1 :(得分:0)
即使你只有“几个”多边形物理体,每个额外的矩形物理体,无论它是否在移动,都需要与每个帧中计算的每个多边形物理体的距离(因此b2Distance()func) 。尝试降低多边形物理实体的复杂性/数量,以提高帧速率。
我怀疑性能突然下降与缓存(b2SimplexCache)有关,缓存(b2SimplexCache)存储这些距离达到其最大容量(可能约为30个值),此时缓存未命中率正在降低帧速率。 iOS 10必须增加此缓存。另一个解决方案是在iOS 9中以某种方式增加此功能的缓存,尽管我不确定如何。