SKSpriteNode碰撞后堆叠粘连 无法重叠穿过的问题该如何解决?
SKSpriteKit节点碰撞粘连解决方案
问题根因
你预期节点之间可互相重叠穿透、无碰撞效果,但实际出现粘连卡顿,核心是SpriteKit物理引擎仍在处理节点间的碰撞交互,大概率是sks添加的节点物理参数配置和代码添加的节点不一致,或是静态节点手动位移时物理引擎缓存未更新导致。
可行解决方案
- 统一所有节点(含sks文件创建的节点)的物理参数
- 所有不需要参与物理碰撞的节点,直接将
physicsBody设为nil即可,没有物理体就完全不会触发任何物理碰撞逻辑,是最彻底的解决方案 - 如果需要保留物理体用于其他逻辑,必须将三个碰撞掩码全部设为0:
categoryBitMask = .zero、collisionBitMask = .zero、contactTestBitMask = .zero,注意sks编辑器中添加的节点默认会有默认掩码值,需要手动在sks的物理体配置面板中将三个掩码全部修改为0
- 所有不需要参与物理碰撞的节点,直接将
- 修正静态节点的移动逻辑
当前代码中你将节点的isDynamic设为false,这类静态节点物理引擎默认不会同步更新它的碰撞体位置,如果你手动修改position或者用SKAction移动节点,物理引擎残留的旧碰撞体轮廓就会导致移动时出现卡顿粘连的问题。如果需要频繁移动这类节点,要么将isDynamic设为true后关闭重力、摩擦等物理属性,要么直接移除物理体后再做位移 - 排查多余物理属性
检查所有节点物理体的friction(摩擦)、restitution(弹性)、linearDamping(线性阻尼)、angularDamping(角阻尼)属性,不需要物理交互的节点将以上属性全部设为0
参考代码示例
let texture = SKTexture(image: #imageLiteral(resourceName: "cone")) trCone = SKSpriteNode(texture: texture, normalMap: texture) trCone?.size = CGSize(width: 60, height: 65) trCone?.position = CGPoint(x: 153, y: 267) trCone?.zPosition = 15 trCone?.name = trainingStuff.text // 不需要物理交互直接移除物理体 trCone?.physicsBody = nil // 若需保留物理体可使用下方配置 /* trCone?.physicsBody = SKPhysicsBody(texture: SKTexture(image: #imageLiteral(resourceName: "cone")), size: CGSize(width: 60, height: 65)) trCone?.physicsBody?.allowsRotation = false trCone?.physicsBody?.isDynamic = false trCone?.physicsBody?.categoryBitMask = .zero trCone?.physicsBody?.collisionBitMask = .zero trCone?.physicsBody?.contactTestBitMask = .zero trCone?.physicsBody?.friction = 0 trCone?.physicsBody?.restitution = 0 trCone?.physicsBody?.linearDamping = 0 trCone?.physicsBody?.angularDamping = 0 */ myTrainigArr?.append(trCone!) self.myScene!.addChild(trCone!)
问题相关截图


内容的提问来源于stack exchange,提问作者danTheMan
相关产品推荐
相关产品推荐

