简体   繁体   English

删除和读取节点后,SpriteKit SKAction 不起作用

[英]SpriteKit SKAction doesn't work after removing and readding a node

Been banging my head against this for a day now, and I really have no idea what's going on.一天以来我一直在用头撞这个,我真的不知道发生了什么。

I have a very simple setup: an SKNode (let's call it base) which contains another SKNode (sub-base), as well as several SKShapeNode objects.我有一个非常简单的设置:一个 SKNode(我们称之为 base),它包含另一个 SKNode(sub-base),以及几个 SKShapeNode 对象。 At some time, I move one of the SKShapeNode objects (using removeFromParent) from the base node to the sub-base node.有时,我将 SKShapeNode 对象之一(使用 removeFromParent)从基节点移动到子基节点。 Then I apply an SKAction, which moves the node to some arbitrary position.然后我应用 SKAction,它将节点移动到某个任意位置。

Except, that SKAction does not work when the SKShapeNode has been removed and added to the sub-base object.但是,当 SKShapeNode 被删除并添加到子基础对象时,SKAction 不起作用。 If I remove it from the sub-base, and put it back in the base, SKActions once again work.如果我将它从底座中取出,然后放回底座中,SKActions 将再次起作用。

I am completely stumped.我完全被难住了。 Is there some property that gets set on a node when it's added to another node, which isn't getting properly reset when I remove it...?当一个节点被添加到另一个节点时,是否有一些属性会被设置在一个节点上,当我删除它时它没有被正确重置......? I can't imagine this is something that should be happening.我无法想象这是应该发生的事情。

Any ideas would be so very welcome.任何想法都会非常受欢迎。

Update:更新:

Here's some code that I can produce it with.这是我可以使用的一些代码。 This function is inside a subclass of SKNode.此函数位于 SKNode 的子类中。 The class adds a bunch of SKShapeNodes, and it also has this other SKNode called testNode, so, without further ado:该类添加了一堆 SKShapeNode,并且它还有另一个名为 testNode 的 SKNode,所以,不用多说:

-(void) removeThenAdd
{
    [someNode removeFromParent];

    [self.testNode addChild:someNode];

    SKAction* action = [SKAction moveTo:CGPointMake(200, 200) duration:1];

    SKNode* thatSameNodeJustAdded = [self.testNode.children objectAtIndex:0];

    [thatSameNodeJustAdded runAction:action];
}

Another update!另一个更新!

I just found that, if I add an SKAction to the node whilst it is sitting inside the testNode, then after that remove it from the testNode and add it back to its original parent, the action is then activated.我刚刚发现,如果我在节点位于 testNode 内部时将 SKAction 添加到节点,然后将其从 testNode 中删除并将其添加回其原始父节点,则该操作将被激活。 Like, what am I missing here?比如,我在这里错过了什么? This must be some kind of designed behaviour I'm just not using right..这一定是某种设计行为,我只是没有正确使用..

This seems to be a bug in the SDK.这似乎是 SDK 中的一个错误。 I had this issue because I wanted to make advanced sprites (sprites with children, emitters, etc) in their own scene files so that I could selectively load and then add them to my scenes.我遇到这个问题是因为我想在他们自己的场景文件中制作高级精灵(带有孩子、发射器等的精灵),以便我可以有选择地加载然后将它们添加到我的场景中。 I came up with a work around using NSKeyedArchiver and NSKeyedUnarchiver -- Convert the node (or parent node) to data, and then back again, and the new object is ready to be added to a scene, if it's an emitter, or has child nodes that are emitters they will all be copied through and properly re-added.我想出了一个使用 NSKeyedArchiver 和 NSKeyedUnarchiver 的解决方法——将节点(或父节点)转换为数据,然后再返回,新对象已准备好添加到场景中,如果它是一个发射器,或者有子节点作为发射器的节点,它们都将被复制并正确地重新添加。 Here is the extension I made for swift, works like a charm:这是我为 swift 制作的扩展,就像一个魅力:

extension SKNode {
    // Pulling a node from one scene and putting it into another causes some problems with broken emitters :(
    // Fix here is to archive and then unarchive the node before returning
    class func nodeFromScene(nodeName : String, sceneFileName : String) -> SKNode? {
        if let scene = SKScene(fileNamed: sceneFileName), node = scene.childNodeWithName(nodeName) {
            let archive = NSKeyedArchiver.archivedDataWithRootObject(node)
            return NSKeyedUnarchiver.unarchiveObjectWithData(archive) as? SKNode
        }
        return nil
    }
}

I was also seeing this issue occur in my SpriteKit project.我也在我的 SpriteKit 项目中看到了这个问题。 In my case I was removing a node from an SKScene file I'd created in the Scene Editor and adding it to my current scene.就我而言,我正在从我在场景编辑器中创建的 SKScene 文件中删除一个节点,并将其添加到我当前的场景中。

Following some debugging it showed that the actions weren't being run at all.经过一些调试,它表明这些操作根本没有运行。 And upon further investigation I discovered why... it seems that when you add a node to the scene in this manner the isPaused property is set to true .经过进一步调查,我发现了原因……似乎当您以这种方式向场景中添加节点时, isPaused属性设置为true Whether this is intentional or a bug I can't find out for sure.这是故意的还是错误,我无法确定。

From the docs: https://developer.apple.com/documentation/spritekit/sknode/1483113-ispaused来自文档: https : //developer.apple.com/documentation/spritekit/sknode/1483113-ispaused

isPaused已暂停

If the value is true, the node (and all of its descendants) are skipped when a scene processes actions.如果该值为真,则在场景处理动作时会跳过该节点(及其所有后代)。

So in order to "fix" this issue, before running any SKActions on the node, unpause the node:因此,为了“修复”这个问题,在节点上运行任何 SKActions 之前,取消暂停节点:

node.isPaused = false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM