Intereting Posts
Необязательное свойство Int содержит ноль вместо нуля во время миграции Как заставить UISlider двигаться плавно? Внедрение пользовательского уровня после серии MPSCNNConvolution Как сделать запрос на localhost через устройство iOS (используя Xcode)? Как установить текстовые параметры UILabel Как я могу использовать ES6 / ES2015 с живой перезагрузкой с помощью Apache Cordova? Как добавить объекты UIColor в NSMutableArray в iOS Как связать два вида коллекции, которые связаны друг с другом? Xamarin IOS SIGSEGV при отладке Mapbox не загружает улицы и детали: Не удалось загрузить mapbox: //mapbox.mapbox-streets-v6 Как использовать одну сцену UIStoryboard с UITableViewController и resultsTableViewController совместно с UISearchController? Как читать IOS Healthkit артериальное давление (систолическое, диастолическое) с использованием HKObserverquery? Настроить метку на основе размера текста в Xamarin IOS Что доступно во время отключения сайта Apple Developer? iOS 4.1 черный экран перед воспроизведением видео с помощью MPMoviePlayerViewController

SceneKit: как обнаружить контакт без столкновения iOS

Я делаю игру Space Shooter на Scene Kit, и я хочу, чтобы астероиды взорвались, когда корабль контактирует с ними, я не хочу, чтобы они сталкивались, я просто хочу знать, когда они контактируют друг с другом.

Проблема в том, что я не знаю, как реализовать обнаружение столкновения, когда корабль пересекает астероид. Например, я хочу, чтобы Xcode записывал «COLLIDED», когда они фактически общались друг с другом.

Я уже добавил categoryBitMask и collisionBitMask для обоих объектов. Итак, как я мог добиться этого? Кстати, я делаю все на Swift.

SceneKit не предлагает возможности для разделения обнаружения контактов от разрешения столкновения для динамических тел. (Если одно из ваших тел является кинематическим телом, оно не будет иметь столкновений, разрешенных против него, но оно не будет перемещаться по физике.) Файл запроса функции ?

Тем не менее, похоже, что ваш прецедент совместим с разрешением столкновения – потому что астероиды взрываются, вам не нужно заботиться о последствиях столкновения на астероиде (просто удалите его со сцены и замените его взрывом VFX, меньшие астероиды, космические пули, что угодно). Если корабль предназначен для выживания столкновения, и вы не хотите, чтобы на него повлияло столкновение, просто установите относительные массы корабля и астероида, чтобы астероид не придавал значительного импульса.


Чтобы делать что-то, когда происходит столкновение, вам нужно установить делегата-контакта в мир физики вашей сцены . В любом классе, который служит вашим делегатом-контактом, didBeginContact метод didBeginContact для уведомления о возникновении столкновения.

В этом методе вам нужно будет посмотреть nodeA контакта nodeA и nodeB чтобы узнать, какие категории тел столкнулись (а какие есть). Как только вы это знаете, например, nodeA является кораблем, а nodeB является астероидом (или наоборот), вы можете убить астероид, обновить свою оценку и т. Д.

Я получил это, чтобы работать с гораздо более простым ответом.

На узле, который вы хотите пропустить, установите физическую массу на очень небольшое число:

 ship.physicsBody.mass = 0.00000000000001; 

В конце я понял, как это решить.

Сначала я добавил categoryBitMask и collisionBitMask для обоих объектов, космического корабля и астероидов.

 ship.physicsBody?.categoryBitMask = 2 asteroid.physicsBody?.categoryBitMask = 4 ship.physicsBody?.collisionBitMask = 4 ball.physicsBody?.collisionBitMask = 2 

Затем я дал dynamicBody() для обоих из них.

 ship.physicsBody = SCNPhysicsBody.dynamicBody() asteroid.physicsBody = SCNPhysicsBody.dynamicBody() 

Затем я добавил NSTimer чтобы помочь мне с обнаружением контакта обновить каждые 0,1 секунды, чтобы увидеть, есть ли контакт.

 override func viewDidLoad() { NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "checkContact", userInfo: nil, repeats: true) } func checkContact() { if (self.scene.physicsWorld.contactTestBetweenBody(ship.physicsBody, andBody: asteroid.physicsBody, options: nil) != nil) { println("CONTACT!") } } 

Мне не нужно было добавлять SCNPhysicsContactDelegate к моему представлению, но лучше добавить его, чтобы убедиться, что нет синтаксических проблем или предупреждений.

Вот и все!

ПРИМЕЧАНИЕ. Важно добавить dynamicBody() или staticBody() к нашим 3D-объектам, иначе у него не будет контакта. И важно добавить dynamicBody() или staticBody() в наши 3D-объекты, прежде чем мы добавим их в качестве ребенка в нашу сцену.

Надеюсь, это поможет кому-то!