Alexander Langer Alexander Langer - 2 months ago 23
Objective-C Question

Scenekit: Objects become invisible after several objects are added (Objective-C)

I am building a game with SceneKit. It is based on SCNBoxes which get added and removed. At the end there are like 30 boxes added to the root node.

// Prepare Surface Layer for Blocks
self.colorOfBlock = [CALayer layer];
self.colorOfBlock.frame = CGRectMake(0, 0, 1000, 1000);
self.colorOfBlock.backgroundColor = [UIColor colorWithHue:0 saturation:1 brightness:1 alpha:1].CGColor;

self.textLayer = [CATextLayer layer];
self.textLayer.frame = self.colorOfBlock.bounds;
self.textLayer.fontSize = 750;//self.colorOfBlock.bounds.size.height;
self.textLayer.string = @"2";
self.textLayer.alignmentMode = kCAAlignmentCenter;
self.textLayer.foregroundColor = [UIColor blackColor].CGColor;

[self.textLayer display];
[self.colorOfBlock addSublayer:self.textLayer];

// Prepare Material for the Block
SCNMaterial *material = [SCNMaterial material];
material.diffuse.contents = self.colorOfBlock;

// Create the Block
self.blockNode = [SCNNode node];
self.blockNode.geometry = [SCNBox boxWithWidth:0.95 height:0.95 length:0.95 chamferRadius:0.1];
self.blockNode.geometry.firstMaterial = material;
self.blockNode.position = position;

// Setup the physics body
self.blockNode.physicsBody = [SCNPhysicsBody dynamicBody];
self.blockNode.physicsBody.affectedByGravity = NO;
self.blockNode.physicsBody.categoryBitMask = CollisionCategoryBlock;
self.blockNode.physicsBody.contactTestBitMask = CollisionCategoryBorder | CollisionCategoryBlock;
self.blockNode.physicsBody.collisionBitMask = CollisionCategoryBorder | CollisionCategoryBlock;
self.blockNode.physicsBody.angularVelocityFactor = SCNVector3Make(0, 0, 0);

[self addChildNode:self.blockNode];

self.gameValue = 2;
if (position.z < 1) {
self.name = @"Front";
} else {
self.name = @"Back";
}


After a while the textLayer seem to disappear. If new blocks are added, they have no textLayer anymore. And another side effect is that old textLayers on the existing blocks are not updated anymore.

On the next step newly added blocks become invisible. Or better to say - they never get a CALayer. But the physicsBodies are still working.

And sometimes the view crashes. The debugger says something like the position of the crashing area can not be found. After this the view is deformed. But I still can call SCNActions that clears the view and shows up all created Objects that are NOT these blocks like I posted. These blocks are totally kicked out of the view.

By the way when I setup the "phonglighttype" for those blocks this bugging cascade happens earlier.

There is also one more thing I noticed. When I tab out of the App (tested from iPhone 5) and tabbed in again after a while, the

self.gameView.showsStatistics = YES;


shows on the GPU bar a blue line. After 2 or 3 sec, the blue bar is gone and a full green GPU bar shows that it is ready for getting used. And everything works like it should do. After a while these blocks become invisible again. If I tab out and tab in again, newly added Blocks are visible again.

Somehow I think of that I am spamming my device cache until the App crashes. But there is no useful hint from Xcode. I wonder if an option to clear the viewControllers cache might solve this problem - if there is an option for this.

Kind Regards

Answer

I did not solved it completely, but I decided to replace every part of CALayer and CATextLayer with a common

material.diffuse.contents = [arrayOfTextures objectAtIndex:certainImage];

With a higher resolution (like Iphone 6 has) it did show up that the CALayer was causing some kind of graphical faulting. But the simple pre-worked image (from an imageArray) solution improves the performance pretty much and prevents from crashing.

I can not surely say if there is no way to solve it with the CALayer approach. But loading images as Material and updating them brought the most satisfying result.

Comments