我有2d级别所以我把它分成更多的.sks文件。我有" GameScene"我可以通过拖放操作在场景编辑器中加入它们。它创建了SKReferenceNodes。我成功地做到了这一点。但我想在代码中需要时懒洋洋地加载这些部分(它被认为是一种很好的做法)。我失败了。
这是代码的特殊部分:
if let nextPart = SKReferenceNode(fileNamed: "Scene2_city2") {
if self.childNodeWithName("Scene2_city2") == nil {
self.addChild(nextPart)
}
}
" Scene2_city2"是.sks文件的名称,也是文件中的场景名称。
运行代码我收到错误:
***由于未被捕获的异常终止应用程序'无法添加正文,已经存在于一个世界中,原因:'无法添加正文类型:表示对象:[名称:' Scene2_city2& #39; frame:{{ - 0,-0},{1024,768}} anchor:{0,0}},已经存在于一个世界中'
这很奇怪,因为我在添加之前先检查它。
问题:如何以编程方式将SKReferenceNode添加到SKScene?
编辑:这是bitbucket上的simple example project。添加参考场景以进行点击。
答案 0 :(得分:9)
我找到了一种解决方法,但事实证明使用SKReferenceNode
方法创建URL
时没有问题。
例如:
let path = NSBundle.mainBundle().pathForResource("SpaceShip", ofType: "sks")
let spaceShip = SKReferenceNode (URL: NSURL (fileURLWithPath: path!))
addChild(spaceShip)
我做了一点挖掘,当使用SKReferenceNode
创建fileNamed
时,它出现在7.3.1 vs 7.2.1中,现在它返回一个可选项。打开时,你会得到SKScene
,如果你尝试将它作为一个孩子添加到现有场景中,它当然会抛出错误。
添加了快速7.3测试项目https://github.com/cocojoe/SKReferenceNodeIssue/tree/workaround
请注意,您在Apple论坛上引用了我的帖子。我填写了一个月前的错误报告,根据过去的经验,这些可能需要一段时间才能看到。
答案 1 :(得分:1)
您已检查节点是否在场景的层次结构中。此错误与物理世界有关,它与节点已添加到场景中的事实无关。
我个人无法使用SKReferenceNode重现您所说的内容,但这可能是因为我并不完全了解您当前的设置。
如果两个节点指向同一个SKPhysicsBody
实例,则会发生此错误,如下所示:
override func didMoveToView(view: SKView) {
let sprite = SKSpriteNode(color: .purpleColor(), size: CGSize(width: 20, height: 20))
let sprite2 = SKSpriteNode(color: .purpleColor(), size: CGSize(width: 20, height: 20))
sprite.position = CGPoint(x:frame.midX, y:frame.midY)
sprite2.position = CGPoint(x:frame.midX, y:frame.midY + 100)
let sharedPhysicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: -10, height: -10))
sprite.physicsBody = sharedPhysicsBody
sprite2.physicsBody = sharedPhysicsBody
addChild(sprite)
addChild(sprite2)
}
此代码将因您当前收到的错误而崩溃。因此,检查您是否在某处或类似地使用相同的SKPhysicsBody,您将解决此问题。
答案 2 :(得分:1)
我遇到了同样的问题。如果我使用SKReferenceNode(fileNamed :)从scene.sks文件中存在的sprite创建一个新的sprite我得到错误
'无法添加身体,已经存在于一个世界中
这似乎与物理有关,并且在使用addChild将对象添加到场景时发生。如果将物理体设置为零,则错误消失。类似的东西:
let newBox = SKReferenceNode(fileNamed: "Box")
newBox?.physicsBody = nil
newBox?.position = location
addChild(newBox!)
有趣的是,即使将physics选项设置为none,也会出现错误。上面的解决方案适用于这种情况,但你失去了物理机构。
对我来说似乎有用的是创建一个用作源对象的对象,并使用skNode.copy()创建它的副本。
答案 3 :(得分:0)
我找到了另一种不会迫使你将physicsBody设置为nil的解决方法。
就我而言,我用SKScene替换了SKReferenceNode。
我首先确保在我的.sks场景中,所有SKSpriteNodes都是一个主节点的子节点。它不必是一个直接的链接,你仍然可以尊重场景的层次结构,但重要的是在层次结构树的末尾#34;它们链接到一个节点,在我的例子中是背景,但它也可以是一个空节点。
在我的GameScene文件中,我编写了以下代码:
class GameScene: SKScene {
var mainNode: SKNode? = nil
override func didMove(to view: SKView) {
var mySksScene = SKScene(fileNamed: "Caribbeans")
mainNode = upperBackground?.childNode(withName: "backgroundCaribbean")
mainNode?.removeFromParent()
mySksScene = nil
addChild(mainNode)
}
}
我首先声明了一个可选的SKNode变量。然后,在didMove(:to :)中,我将.sks文件加载到可选的SKScene()变量中。然后我将SKNode设置为主节点,该节点是所有其他节点的父节点(在我的例子中:backgroundCaribbean)。然后我从我的父场景中删除了我的mainNode,然后设置为nil用于包含.sks场景的变量,只有那时我将我的mainNode添加为我的GameScene的Child。