Sprite kit 从SKView获取SpriteKit纹理在104次调用后返回nil
在创建纹理时,我在SpriteKit中有一些奇怪的行为。下面的函数显示我正在做什么。简而言之,我在SceneKit中,用一系列颜色(想想像素/体素)制作一个SCNNode。它就像一个符咒。但是,在精确调用104次之后,返回的纹理为nil。之后,无论纹理是否为零,都会命中或未命中。我也提供确切的颜色信息。想法Sprite kit 从SKView获取SpriteKit纹理在104次调用后返回nil,sprite-kit,scenekit,Sprite Kit,Scenekit,在创建纹理时,我在SpriteKit中有一些奇怪的行为。下面的函数显示我正在做什么。简而言之,我在SceneKit中,用一系列颜色(想想像素/体素)制作一个SCNNode。它就像一个符咒。但是,在精确调用104次之后,返回的纹理为nil。之后,无论纹理是否为零,都会命中或未命中。我也提供确切的颜色信息。想法 func create2dModelSK(with colors: [String]) -> SCNNode? { let geo = SCNBox(width: 1.0
func create2dModelSK(with colors: [String]) -> SCNNode? {
let geo = SCNBox(width: 1.0, height: 1.0, length: 0.1, chamferRadius: 0.0)
let base = SCNNode(geometry: geo)
let view = SKSpriteNode(color: .white, size: CGSize(width: 160, height: 160))
view.anchorPoint = CGPoint(x: 0, y: 1)
var xOffset = 0
var yOffset = 0
var count = 0
for _ in 0...15 {
for _ in 0...15 {
guard let newColor = UIColor(hexString: "#" + colors[count] + "ff") else { return base }
let n = SKSpriteNode(color: newColor, size: CGSize(width: 10, height: 10))
n.anchorPoint = CGPoint(x: 0, y: 1)
n.position = CGPoint(x: xOffset, y: yOffset)
view.addChild(n)
xOffset += 10
count += 1
}
xOffset = 0
yOffset -= 10
}
let skView = SKView(frame: CGRect(x: 0, y: 0, width: 160, height: 160))
let texture = skView.texture(from: view)
//AFTER being called 104 times, texture is nil.
let faceMaterial = SCNMaterial()
faceMaterial.diffuse.contents = texture
let sideMaterial = SCNMaterial()
sideMaterial.diffuse.contents = UIColor.white
let materialsForBox = [faceMaterial,sideMaterial,faceMaterial,sideMaterial,sideMaterial,sideMaterial]
base.geometry?.materials = materialsForBox
let scale = SCNVector3(x: 0.1, y: 0.1, z: 0.1)
base.scale = scale
return base
}
这是
autoreleasepool
方便的地方,它允许您在autoreleasepool
完成时释放内存,这样您就不会在再次使用它之前耗尽空间
当然,这并不能解决您的主要问题,即您创建的纹理太多,并且内存空间不足,但它至少允许您制作更多的纹理,因为它将释放view.texture(from:node)
保留的临时内存
func create2dModelSK(with colors: [String]) -> SCNNode? {
let geo = SCNBox(width: 1.0, height: 1.0, length: 0.1, chamferRadius: 0.0)
let base = SCNNode(geometry: geo)
let view = SKSpriteNode(color: .white, size: CGSize(width: 160, height: 160))
view.anchorPoint = CGPoint(x: 0, y: 1)
var xOffset = 0
var yOffset = 0
var count = 0
for _ in 0...15 {
for _ in 0...15 {
guard let newColor = UIColor(hexString: "#" + colors[count] + "ff") else { return base }
let n = SKSpriteNode(color: newColor, size: CGSize(width: 10, height: 10))
n.anchorPoint = CGPoint(x: 0, y: 1)
n.position = CGPoint(x: xOffset, y: yOffset)
view.addChild(n)
xOffset += 10
count += 1
}
xOffset = 0
yOffset -= 10
}
autoreleasepool{
let skView = SKView(frame: CGRect(x: 0, y: 0, width: 160, height: 160))
let texture = skView.texture(from: view)
//AFTER being called 104 times, texture is nil.
let faceMaterial = SCNMaterial()
faceMaterial.diffuse.contents = texture
let sideMaterial = SCNMaterial()
sideMaterial.diffuse.contents = UIColor.white
let materialsForBox = [faceMaterial,sideMaterial,faceMaterial,sideMaterial,sideMaterial,sideMaterial]
base.geometry?.materials = materialsForBox
}
let scale = SCNVector3(x: 0.1, y: 0.1, z: 0.1)
base.scale = scale
return base
}
纹理空间即将用完。请避免调用节点“视图”,因为这只会增加混淆。谢谢您的快速回答。有没有更好的方法来考虑添加这么多纹理?我不认为我需要超过1000个。你想做什么?我正在给ARKit场景添加SCNNodes。每个节点都需要自己的纹理以及提供给上述函数的数据。数据是从多个位置提供的,但它们都会反馈到场景中。此外,在您的答案中调用autoreleasepool也不起作用,因为它变成了自己的范围。