SceneKit의 SCNPhysicsContactDelegate에서 충돌 결정
SCNPhysicsContactDelegate
자주 사용된다고 생각하는 것이, SCNPhysicsContactDelegate 그리고, 당 판정이 발생했을 때에 불리는 메소드가 이하와 같이 정의되고 있습니다.
didBegin, didUpdate, didEnd로 불리는 3 종류의 메소드가 있어, 각각 불리는 타이밍이 다릅니다. 이번은 물체끼리의 충돌이 끝나면 불리는, didBegin을 예로, 실제로 2개의 물체가 부딪쳤을 때의 핸들링 방법을 간단하게 소개합니다.
우선은 Delegate를 세트
먼저 sceneView.scene.physicsWorld의 contactDelegate에 ViewController를 설정합니다.
override func viewDidLoad() {
super.viewDidLoad()
sceneView.scene.physicsWorld.contactDelegate = self
}
extension ViewController: SCNPhysicsContactDelegate {
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
}
}
맞으면 호출되는 메서드 정의
그리고 SCNPhysicsContactDelegate의 physicsWorld (didBegin을 정의합니다.
인수에는 SCNPhysicsWorld와 SCNPhysicsContact가 있으며, 전자는 환경의 정보, 후자는 당 판정의 정보입니다.
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
let nodeA = contact.nodeA
let nodeB = contact.nodeB
}
다음과 같은 경우에는 contact.nodeA 또는 contact.nodeB에 파란색 공 또는 빨간 마토의 Node가 각각 설정되어 있습니다.
당 판정을 실시한다
예를 들면, 다음과 같이 적의 Node와 볼의 Node가 정의되어 있다고 합시다.
let matoNode = SCNNode()
matoNode.name = "mato"
let ballNode = SCNNode()
ballNode.name = "ball"
그 경우 SCNPhysicsContactDelegate의 메소드에 있어서, 이하와 같이 맞았는지 어떤지를 판정합니다. (더 똑똑한 쓰기 방법이있을 수 있습니다)
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
let nodeA = contact.nodeA
let nodeB = contact.nodeB
if (nodeA.name == "mato" && nodeB.name == "ball") || (nodeB.name == "mato" && nodeA.name == "ball") {
// 当たった!!
}
}
치면 햅틱 피드백을 하거나 상대방에게 정보를 전송하여 슈팅 배틀을 수립할 수 있습니다.
당 판정을 실시하기 위한 Node의 설정
실은, 단지 단순히 Node를 설정한 것만으로는, 당 판정은 발화하지 않습니다. 먼저 올린 마토의 Node와 볼의 Node를 각각 구체적으로 설정해 봅시다.
마토의 노드
SCNPhysicsShape를 설정해야 합니다. geometry를 인수에 걸립니다.
let cylinder = SCNCylinder(radius: 0.1, height: 0.05)
let matoNode = SCNNode(geometry: box)
node.name = "mato"
node.position = SCNVector3Make(0, 0, -1.5)
// add PhysicsShape
let shape = SCNPhysicsShape(geometry: cylinder, options: nil)
node.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
node.physicsBody?.isAffectedByGravity = false
공의 Node
맞는 쪽의 SCNPhysicsBody에 contactTestBitMask를 설정하는 것을 잊지 마세요!
이쪽 디폴트는 0입니다만, 그대로라면 당 판정이 발화하지 않습니다.
let ball = SCNSphere(radius: 0.1)
ball.firstMaterial?.diffuse.contents = UIColor.blue
let ballNode = SCNNode(geometry: ball)
ballNode.name = "ball"
// add PhysicsShape
let shape = SCNPhysicsShape(geometry: ball, options: nil)
ballNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
ballNode.physicsBody?.contactTestBitMask = 1
ballNode.physicsBody?.isAffectedByGravity = false
이상!
요약
override func viewDidLoad() {
super.viewDidLoad()
sceneView.scene.physicsWorld.contactDelegate = self
}
extension ViewController: SCNPhysicsContactDelegate {
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
}
}
그리고 SCNPhysicsContactDelegate의 physicsWorld (didBegin을 정의합니다.
인수에는 SCNPhysicsWorld와 SCNPhysicsContact가 있으며, 전자는 환경의 정보, 후자는 당 판정의 정보입니다.
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
let nodeA = contact.nodeA
let nodeB = contact.nodeB
}
다음과 같은 경우에는 contact.nodeA 또는 contact.nodeB에 파란색 공 또는 빨간 마토의 Node가 각각 설정되어 있습니다.
당 판정을 실시한다
예를 들면, 다음과 같이 적의 Node와 볼의 Node가 정의되어 있다고 합시다.
let matoNode = SCNNode()
matoNode.name = "mato"
let ballNode = SCNNode()
ballNode.name = "ball"
그 경우 SCNPhysicsContactDelegate의 메소드에 있어서, 이하와 같이 맞았는지 어떤지를 판정합니다. (더 똑똑한 쓰기 방법이있을 수 있습니다)
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
let nodeA = contact.nodeA
let nodeB = contact.nodeB
if (nodeA.name == "mato" && nodeB.name == "ball") || (nodeB.name == "mato" && nodeA.name == "ball") {
// 当たった!!
}
}
치면 햅틱 피드백을 하거나 상대방에게 정보를 전송하여 슈팅 배틀을 수립할 수 있습니다.
당 판정을 실시하기 위한 Node의 설정
실은, 단지 단순히 Node를 설정한 것만으로는, 당 판정은 발화하지 않습니다. 먼저 올린 마토의 Node와 볼의 Node를 각각 구체적으로 설정해 봅시다.
마토의 노드
SCNPhysicsShape를 설정해야 합니다. geometry를 인수에 걸립니다.
let cylinder = SCNCylinder(radius: 0.1, height: 0.05)
let matoNode = SCNNode(geometry: box)
node.name = "mato"
node.position = SCNVector3Make(0, 0, -1.5)
// add PhysicsShape
let shape = SCNPhysicsShape(geometry: cylinder, options: nil)
node.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
node.physicsBody?.isAffectedByGravity = false
공의 Node
맞는 쪽의 SCNPhysicsBody에 contactTestBitMask를 설정하는 것을 잊지 마세요!
이쪽 디폴트는 0입니다만, 그대로라면 당 판정이 발화하지 않습니다.
let ball = SCNSphere(radius: 0.1)
ball.firstMaterial?.diffuse.contents = UIColor.blue
let ballNode = SCNNode(geometry: ball)
ballNode.name = "ball"
// add PhysicsShape
let shape = SCNPhysicsShape(geometry: ball, options: nil)
ballNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
ballNode.physicsBody?.contactTestBitMask = 1
ballNode.physicsBody?.isAffectedByGravity = false
이상!
요약
let matoNode = SCNNode()
matoNode.name = "mato"
let ballNode = SCNNode()
ballNode.name = "ball"
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
let nodeA = contact.nodeA
let nodeB = contact.nodeB
if (nodeA.name == "mato" && nodeB.name == "ball") || (nodeB.name == "mato" && nodeA.name == "ball") {
// 当たった!!
}
}
실은, 단지 단순히 Node를 설정한 것만으로는, 당 판정은 발화하지 않습니다. 먼저 올린 마토의 Node와 볼의 Node를 각각 구체적으로 설정해 봅시다.
마토의 노드
SCNPhysicsShape를 설정해야 합니다. geometry를 인수에 걸립니다.
let cylinder = SCNCylinder(radius: 0.1, height: 0.05)
let matoNode = SCNNode(geometry: box)
node.name = "mato"
node.position = SCNVector3Make(0, 0, -1.5)
// add PhysicsShape
let shape = SCNPhysicsShape(geometry: cylinder, options: nil)
node.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
node.physicsBody?.isAffectedByGravity = false
공의 Node
맞는 쪽의 SCNPhysicsBody에 contactTestBitMask를 설정하는 것을 잊지 마세요!
이쪽 디폴트는 0입니다만, 그대로라면 당 판정이 발화하지 않습니다.
let ball = SCNSphere(radius: 0.1)
ball.firstMaterial?.diffuse.contents = UIColor.blue
let ballNode = SCNNode(geometry: ball)
ballNode.name = "ball"
// add PhysicsShape
let shape = SCNPhysicsShape(geometry: ball, options: nil)
ballNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
ballNode.physicsBody?.contactTestBitMask = 1
ballNode.physicsBody?.isAffectedByGravity = false
이상!
요약
샘플 코드
htps : // 기주 b. 코 m / k 보 y-시 lゔぇrgym / 아 의 Physics에 있습니다!
유용한 기사
Reference
이 문제에 관하여(SceneKit의 SCNPhysicsContactDelegate에서 충돌 결정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kboy/items/b557bdd2922ca4fbb1c6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)