I have a SpriteKit platformer that uses a tile map for a background. The background in question is positioned 1 screen-height above the main content (it's positioned off-screen), acting as a forest canopy above the player. I accomplish that programmatically, like this:
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
let columns = 20
let rows = 1
let tileSize = CGSize(width: screenWidth, height: screenHeight)
let container = SKSpriteNode()
let tileDefinition = SKTileDefinition(texture: MainData.textureAtlas.textureNamed("someTexture"), size: CGSize(width: screenWidth, height: screenHeight))
let tileGroup = SKTileGroup(tileDefinition: tileDefinition)
let tileSet = SKTileSet(tileGroups: [tileGroup])
let layer = SKTileMapNode(tileSet: tileSet, columns: columns, rows: rows, tileSize: tileSize)
container.position = CGPoint(x: screenWidth*0.5, y: screenHeight*1.5)
container.size = CGSize(width: CGFloat(columns)*screenWidth, height: screenHeight)
container.zPosition = 3.0
layer.fill(with: tileGroup)
container.addChild(layer)
addChild(container)
A camera node follows the player.
The problem: If the player jumps up, the SKTileMapNode
disappears when he comes back down. It never reappears. Its parent node, container
, remains visible, so I think the problem is with the SKTileMapNode
, not the container
.
What I've tried:
I've tried the following, with numbers 2-5 being checked for the SKTileMapNode
:
view.shouldCullNonVisibleNodes = false
.alpha
value. It's always 1.0
.position
. It's always CGPoint(x: 0, y: 0)
.anchorPoint
. It's always CGPoint(x: 0.5, y: 0.5)
.zPosition
. It does not change, and there are no other nodes that could be obscuring the SKTileMapNode
or its parent. Setting a higher value has no effect on the problem.container
remains visible. It does.On culling:
It seems like the problem should be related to culling, but setting view.shouldCullNonVisibleNodes=false
has no effect on the situation. I also checked to make sure the SKTileMapNode
is always present as a child node of container
. It is. I suppose this means that the node is not being culled. However, if I position container
so that it's always on-screen, the problem does not occur at all; the SKTileMapNode
remains visible. This leaves me very confused because it seems like these are conflicting facts.
On devices: Using the simulator, at least, the problem does not occur on the older-style iPhones such as the SE and the iPhone 8. It only happens on the newer iPhones, such as the iPhone 11 and iPhone 12. Having access to an iPhone 11, I can confirm that the problem is occurring on real devices, too.
Question: Why is my SKTileMapNode
disappearing when off-camera (even with culling disabled)? How can I keep this node visible?
Thank you!
It seems that I've solved the problem.
I'm presenting my scene via SwiftUI SpriteView
, which I had configured to allow background transparency, like this:
SpriteView(scene: theScene, options: [.allowsTransparency])
Removing the transparency option solved the problem:
SpriteView(scene: theScene)
Now, why should this be the case? I have no idea.