swift - Occasional stuttering with SceneKit when touching the screen
问题描述
When I interact with the screen the objects in my game start to stutter. My FPS is at 60 and doesn't drop but the stuttering is still prevalent. I believe my problem is how I'm animating the objects on screen(code below).If anybody could help I would appreciate it.
I have an x amount of nodes inside an array called _activePool. In the Update function I am moving the nodes x position inside _activePool, adding new nodes when the last node in _activePool position is <= 25 and removing the first node in _activePool if it's position is <= -25.
if _cycleIsActive{
for obj in _activePool{
//move the obj in _activePool
obj.position.x += Float(dt * self.speedConstant);
}
let lastObj = _activePool.last;
if (lastObj?.position.x)! + getWidthOfNode(node: lastObj!) + Float(random(min: 15, max: 20)) <= 25{
// get new obj(pattern) and add to _activePool
self.getPatternData(sequencePassedIn: selectedSeq, level: self._currentLevel, randomPattern: randomPattern());
}
let firstObj = _activePool.first;
if (firstObj?.position.x)! + getWidthOfNode(node: firstObj!) <= -25{
// remove object and return to specific pool
firstObj?.removeFromParentNode();
returnItems(item: firstObj!);
_activePool.removeFirst();
}
}
I create several arrays and add them to a dictionary
func activatePools(){
temp1Pool = ObjectPool(tag: 1, data: []);
dictPool[(temp1Pool?.tag)!] = temp1Pool;
temp2Pool = ObjectPool(tag: 2, data: []);
dictPool[(temp2Pool?.tag)!] = temp2Pool;
for i in 0... dictPool.count {
obstacleCreationFactory(factorySwitch: i);
}
}
Creating my obstacles(enemies)
func obstacleCreationFactory(factorySwitch: Int){
Enemies = Enemy();
switch factorySwitch {
case 0:
for _ in 0...100{
let blueEnemy = Enemies?.makeCopy() as! Enemy
blueEnemy.geometry = (Enemies?.geometry?.copy() as! SCNGeometry);
blueEnemy.geometry?.firstMaterial?.diffuse.contents = UIColor.blue;
blueEnemy.tag = 1;
temp1Pool?.addItemToPool(item: blueEnemy);
}
case 1:
for _ in 0...100{
let redEnemy = Enemies?.makeCopy() as! Enemy
redEnemy.geometry = (Enemies?.geometry?.copy() as! SCNGeometry);
redEnemy.geometry?.firstMaterial?.diffuse.contents = UIColor.red;
redEnemy.tag = 2;
temp2Pool?.addItemToPool(item: redEnemy);
}
default:
print("factory error");
}
}
解决方案
如果无法查看您的代码库的其余部分,真的很难猜测是什么导致了您的问题。
如果您在某个地方的某个循环中创建了大量临时对象,您可能会考虑创建一个本地自动释放池以防止内存峰值。这是一篇很好的文章,描述了为什么在某些情况下这是一个好主意。
您还可以在计时器或其他东西上调用一些特别昂贵的函数。很难说。
简而言之,您应该考虑使用 Xcode 的 Profiling 工具(称为 Instruments)。具体来说,我建议使用 Time Profiler 来检查哪些函数花费的时间最多并导致这些峰值。
这是一个很棒的 WWDC 会议视频,展示了如何使用时间分析器,我建议定期分析您的应用程序,尤其是当您遇到此类问题时。
推荐阅读
- linux - 通过套接字连接发送/接收 TUI 数据
- selenium - Selenium - 如何验证页面刷新时出现的加载器
- algorithm - 如何创建将相同的长 url 映射到相同的短 url 的 URL 缩短器?
- keras - 使用 VGGFace 权重微调 VGG 模型
- node.js - 节点 mssql 临时表丢失 - RequestError: Invalid object name '#myTempTable'
- semaphore - 如何使用 sem_open 为不同的用户访问相同的信号
- reactjs - TypeError:在使用 react-charts 时尝试解构不可迭代的实例无效
- ios - ios-获取重新安装应用程序后必须相同的唯一标识符
- c++ - 创建具有私有构造函数的类模板的实例
- batch-file - 窗口批处理文件错误:(此时意外