I'm trying to add a hitbox to the bottom of my player to only detect platforms. After a lot of trial and error I figured out to have an additional physicsbody attached as a child in a fixed position to another physicsbody I need to use an SKPhysicsJoint. I did this and it seems to have an unforeseen consequence. when I add the hitbox to the player in this way, it alters the players collision / contact bit masks slightly.
In my game you tap the screen to jump and it works seamlessly with no lag like so:
But when I add this hitbox with the joint I have to hold the screen with my finger and eventually the player jumps, but most of the time the input is ignored. Almost as if there's some sort of severe lag when reading the input.In this gif I'm tapping the screen constantly trying to make my player jump and a lot of the inputs are being ignored or blocked:
This function setups up the player in my gamescene.swift and adds the hitbox to the player via a fixed SKPhysicsJoint to the scene:
func playerSetup(){
//setups player
addChild(player)
player.addChild(playerPlatformHitbox)
let myCGPoint = player.position // sets joint position
let myJoint = SKPhysicsJointFixed.joint(withBodyA: playerPlatformHitbox.physicsBody!, bodyB: player.physicsBody!, anchor: myCGPoint)
scene?.physicsWorld.add(myJoint)
}
And this is the hitbox class I made to only detect platforms for the player. you'll see it should ignore everything expect platforms from the bit masks. For some reason it's not allowing the player to accept contact with it's bit masks even though this hitbox and player arent touching:
import Foundation
import SpriteKit
class PlayerPlatformHitbox: SKSpriteNode{
init() {
super.init(texture: nil, color: SKColor.blue, size: CGSize(width: playerTexture.size().width, height: 10))
physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.size.width, height: self.size.height))
position = CGPoint(x:0, y: (-playerTexture.size().height * 0.6))
physicsBody?.categoryBitMask = CollisionTypes.jumpHitBox.rawValue
physicsBody?.contactTestBitMask = CollisionTypes.platform.rawValue
physicsBody?.collisionBitMask = CollisionTypes.platform.rawValue
physicsBody?.restitution = 0.0
physicsBody?.friction = 0.0
zPosition = 20
physicsBody?.linearDamping = 0.0
physicsBody?.angularDamping = 0.0
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)}
}
And this is my player class
class Player: SKSpriteNode {
init() {
super.init(texture: nil, color: SKColor.clear, size: playerTexture.size())
//starts accelerameter
motionManager = CMMotionManager()
motionManager.startAccelerometerUpdates()
physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: playerTexture.size().width,
height: playerTexture.size().height))
physicsBody?.categoryBitMask = CollisionTypes.player.rawValue
physicsBody?.contactTestBitMask = CollisionTypes.memoryModule.rawValue | CollisionTypes.spikes.rawValue | CollisionTypes.finish.rawValue | CollisionTypes.enemy.rawValue | CollisionTypes.ground.rawValue
physicsBody?.collisionBitMask = CollisionTypes.ground.rawValue | CollisionTypes.sceneEdge.rawValue
physicsBody?.affectedByGravity = true
physicsBody?.restitution = 0.0
physicsBody?.friction = 0.3
physicsBody?.isDynamic = true
//physicsBody?.friction = 0.0
physicsBody?.allowsRotation = false
setScale(0.65)
zPosition = 1
physicsBody?.linearDamping = 0.0
physicsBody?.angularDamping = 0.0
animateWalk()
}
The goal of all this is to use the hitbox to detect platforms instead of the player in this function I have in my update method:
//jump through platform check
if let body = player.physicsBody {
let dy = body.velocity.dy
if dy > 0{
// Prevent collisions if the hero is jumping
body.collisionBitMask &= ~CollisionTypes.platform.rawValue
body.contactTestBitMask &= ~CollisionTypes.platform.rawValue
}
else {
// Allow collisions if the hero is falling
body.collisionBitMask |= CollisionTypes.platform.rawValue
body.contactTestBitMask |= CollisionTypes.platform.rawValue
}
}
and the only reason I need to do this is because when the player is falling, if he falls and hits the side of the platform he will stop and slide down it because collisions are back on and the players physicsbody is a square.
If i can use the platform detection hitbox to detect the platforms instead of the players bulky hitbox it will get rid of this issue.
Thanks for any and all advice.
EDIT: this is the childs behavior with a physics body and no joint: