I have been trying to add a contact delegate to my GameScene:
self.physicsWorld.contactDelegate = ContactManager()
However, I am doing this by having the contact delegate (ContactManager class) on a separate class, to avoid having that much code on my GameScene. This is my contact delegate:
class ContactManager : NSObject, SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {
print("they touched!")
}
}
The problem is that when object 1 collides with object 2 it does not run the method didBegin(). However, I know the problem is not the bitmasks because I made the GameScene inherit the SKPhysicsContactDelete and set the delegate to self and the method didBegin() worked. So the issue is that the class ContactManager() is not linking up correctly, how can I make sure the a contact manager on a separate class from the GameScene works?
contactDelegate on SKPhysicsWorld is unowned(unsafe), which means that it will not increase the retain counter, and will not be treated as an optional.
This means that you are responsible for retaining whatever object you place into this variable.
In your code self.physicsWorld.contactDelegate = ContactManager() You are setting the contact delegate to be a local copy of ContactManager. Since nothing is retaining this, it will immediately be discarded because the retain count is set to 0.
This is the reason why in most cases, people use self as the delegate, because you are guaranteed that self exists.
To remedy this situation, make sure you have a property that retains your ContactManger so that you do not lose it upon creation.
class Example : SKScene
{
let contactManager = ContactManager()
func someKindOfSetup()
{
self.physicsWorld.contactDelegate = contactManager
}
}
Source: https://developer.apple.com/reference/spritekit/skphysicsworld/1449602-contactdelegate
As per Whirlwind:
Only one object can be set as a delegate of a physics world. So if you set
self.physicsWorld.contactDelegate = contactManagerInstance, and later in your code you set it again to self (where self is a scene), only the scene will receive contact notifications. So you can either have a scene listening for the contacts or theContactManager. So basically do what Knight0fDragon said, make a property and set it to be a contact delegate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With