Try this in an iOS/macOS SpriteKit project:
let spriteSize = CGSize(width: 32, height: 32)
let sprite1 = SKSpriteNode(color: .red, size: spriteSize)
let sprite2 = SKSpriteNode(color: .green, size: spriteSize)
let physicsBody1 = SKPhysicsBody(rectangleOf: spriteSize)
sprite1.physicsBody = physicsBody1
scene.addChild(sprite1)
sprite2.physicsBody = physicsBody1
scene.addChild(sprite2)
It will crash during runtime: Terminating app due to uncaught exception 'Cant add body, already exists in a world'
I am writing a game engine library/package. Due to its flexible design, there is a chance for the user to end up with a situation where the same SKPhysicsBody may be added to an SKScene more than once, causing a runtime crash, unless the user is extra-careful at every step.
I want to eliminate the possibility of that crash, and have the app simply log a warning then continue running, but the obvious solutions are not very elegant; I will have to subclass many SpriteKit classes and instruct the users of my library to only inherit from those subclasses, which defeats certain goals of the engine.
-
do-try-catch does not help here because No calls to throwing functions occur within 'try' expression
-
I cannot do anything with SKNode.physicsBody via an extension, because you cannot override properties or add observers in extensions.
Any suggestions?
tkrajacic
(Thomas Krajacic)
2
I have no experience with SpriteKit but I guess those are Objective-C exceptions. Those can't be caught in Swift but people have been writing Objective-C wrappers that catch those exceptions and those wrappers are available in Swift then.
Have a look here for example:
1 Like
ckeithray
(C. Keith Ray)
3
In your code to add a physics body, can you check if aphysicsbody.node is nil before attempting to add it to a node? Or maybe do this every time:
node.physicsBody = aphysicsbody.copy()
...assuming copy() doesn't copy the .node member?