#scenekit #physics #collision
#сценекит #физика #столкновение
Вопрос:
Функция (код ниже) просто перемещает символьный узел (contact.NodeA) обратно после того, как он проник в узел столкновения (contact.NodeB), через который ему запрещено проходить.
В сценарии, когда пользователь пытается переместить узел персонажа (contact.NodeA), пока он застрял в углу и т. Д. сцена/персонаж постоянно трясется/дает сбои, в то время как его положение постоянно удаляется от контакта.NodeB при 60 Гц.
Возможно ли с помощью SCNPhysicsContact в SceneKit в первую очередь предотвратить переход contact.NodeA в contact.NodeB? (т. е., почему вообще происходит «контакт. расстояние проникновения»? Почему мы не можем просто быть предупреждены, когда физический контакт начался без контакта.NodeA фактически переходит в контакт.NodeB? В конце концов, мы ловим контакт на «Дидбегине», но уже есть проникновение, которое мы должны скорректировать.)
(Когда пользователь пытается переместить узел персонажа, когда он «застрял» в углу или между двумя камнями и т. Д.)
Или есть другое решение для предотвращения повторного сотрясения contact.NodeA, поскольку его положение неоднократно корректируется, чтобы компенсировать его проникновение в контакт.NodeB? Трансформироваться вместо изменения положения?
Я уже пробовал установить momentum на 0.0 и удалить все анимации и т. Д. Однако, поскольку контакт все еще происходит с contact.NodeB, contact.NodeA не может быть удален, так как его импульс все еще останавливается во время контакта с NodeB.
Любая помощь будет очень признательна.
private func characterNode(_ characterNode: SCNNode, hitWall wall: SCNNode, withContact contact: SCNPhysicsContact) { if characterNode.name != "collider" { return } if maxPenetrationDistance gt; contact.penetrationDistance { return } var characterPosition = float3(characterNode.parent!.position) var positionOffset = float3(contact.contactNormal) * Float(contact.penetrationDistance) maxPenetrationDistance = contact.penetrationDistance characterPosition.y = positionOffset.y replacementPositions[characterNode.parent!] = SCNVector3(characterPosition) } extension GameViewController : SCNPhysicsContactDelegate { func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) { if gameState != .playing { return } contact.match(BitmaskWall) { (matching, other) in if other.name == "collider" { self.characterNode(other, hitWall: matching, withContact: contact) } } }
Комментарии:
1. похоже на код из демонстрационного приложения Apple Fox 🙂 Я заметил то же самое. К сожалению, я не могу сказать вам, что решает эту проблему — действительно хороший вопрос!
2. ЗАЙ: Действительно, вы правы. Я даже не осознавал этого. Я прошел курс «ты-болван», в котором, должно быть, в качестве учебного материала использовалась демонстрация Fox. Просматривая фактический код приложения Fox, я считаю, что следующая строка и все, что имеет отношение к ней, являются ответом. Я все еще пытаюсь это понять. Если я разберусь, я опубликую это в качестве ответа, чтобы помочь всем, кто может быть заинтересован. (В частности, «Модель collisionShapeOffsetFromModel»): Код персонажа!.simdWorldPosition = Точка замены — модель collisionShapeOffsetFromModel