简体   繁体   English

有时在碰撞明显结束后,最后调用 didBegin 接触,在 didEnd 接触之后 - iOS / SceneKit

[英]Sometimes after a collision clearly ends, didBegin contact is called last, AFTER didEnd contact - iOS / SceneKit

I have 2 nodes properly colliding with each other.我有 2 个节点正确地相互碰撞。 One node is a set of walls and is set as dynamic.一个节点是一组墙并且被设置为动态的。 The other node is a cylinder which follows the camera in an AR view and is set as kinematic.另一个节点是一个圆柱体,它在 AR 视图中跟随相机并设置为运动学。 This is using ARKit, but the collisions are between SceneKit nodes.这是使用 ARKit,但碰撞发生在 SceneKit 节点之间。

The collision works exactly as I want it to and the walls' node moves correctly when the cylinder collides with it.碰撞完全按照我的意愿进行,当圆柱体与其碰撞时,墙壁的节点正确移动。

The problem is that I need to run some code when the collision ended to re-enable a button.问题是我需要在碰撞结束时运行一些代码以重新启用按钮。

In didBegin contact I hide the button as such:didBegin contact中,我隐藏了按钮:

func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
    
    if contact.nodeA.physicsBody?.categoryBitMask == BodyType.wallsCategory.rawValue || contact.nodeB.physicsBody?.categoryBitMask == BodyType.wallsCategory.rawValue {
        
        freezeButton.isHidden = true
    }
}

Then in didEnd contact I re-enable the button like that:然后在didEnd contact中我重新启用按钮:

func physicsWorld(_ world: SCNPhysicsWorld, didEnd contact: SCNPhysicsContact) {
    
    freezeButton.isHidden = false
}

And usually all of this works exactly as I wanted so the button correctly vanishes when a collision occurs and the button comes back when the collision ends.通常所有这些都完全按照我的要求工作,因此当碰撞发生时按钮会正确消失,而当碰撞结束时按钮会返回。

BUT, often when the collision completes, the button does not return.但是,通常当碰撞完成时,按钮不会返回。

I added print statements in didBegin and didEnd and I also added similar labels on screen so I could clearly see when those functions are called.我在didBegindidEnd中添加了打印语句,还在屏幕上添加了类似的标签,这样我就可以清楚地看到这些函数何时被调用。 What I see is that often the last call was to didBegin even after the collision has clearly ended.我看到的是,即使在碰撞明显结束之后,最后一次调用通常也是didBegin I know this because I have SCNDebugOptions.showPhysicsShapes as debugOptions so I can clearly see that the cylinder is not touching the walls at all.我知道这一点是因为我将SCNDebugOptions.showPhysicsShapes作为 debugOptions,所以我可以清楚地看到圆柱体根本没有接触墙壁。

I then need to cause a new collision then walk back to have the didEnd function be called and get my button back.然后我需要引起新的碰撞然后走回去让didEnd function 被调用并取回我的按钮。

I'm not using the didUpdate contact call as I don't need it.我没有使用didUpdate contact电话,因为我不需要它。

How come didBegin is called last when clearly the collision has ended?明明碰撞已经结束,为什么最后调用didBegin What could cause this to happen like that?什么会导致这样的事情发生?

And what could I do to fix this?我能做些什么来解决这个问题?

I am thinking of a workaround which would check if some time has passed since the last didBegin that would indicate this is an old collision.我正在考虑一种解决方法,它会检查自上次didBegin以来是否已经过去了一段时间,这表明这是一次旧碰撞。 Or is there something else I could check if a collision is currently still in progress?或者还有什么我可以检查碰撞当前是否仍在进行中的东西? AFAIK, SceneKit doesn't have a function similar to allContactedBodies as in SpriteKit. AFAIK,SceneKit 没有 function 类似于allContactedBodies中的 allContactedBodies。 Is there something else I could use to check that 2 bodies are still in contact or not?还有什么我可以用来检查 2 具尸体是否仍在接触的东西吗?

Thanks!谢谢!

As a workaround you could probably give the End-Contact statement freezeButton.isHidden = false a small delay like with the DispatchQueue .作为解决方法,您可以像DispatchQueue一样给 End-Contact 语句freezeButton.isHidden = false一个小的延迟。 This will re-enable the button on the next Run-Loop.这将在下一个运行循环中重新启用按钮。 This might not be the perfect solution, but it could give you better results than now.这可能不是完美的解决方案,但它可以为您提供比现在更好的结果。 Give it a try.试一试。

DispatchQueue.main.async { self.freezeButton.isHidden = false }

In addition you could check within the Begin-Contact if the Button is not hidden already, and only hide it if needed.此外,如果 Button 尚未隐藏,您可以在 Begin-Contact 中检查,并且仅在需要时隐藏它。

if !freezeButton.isHidden { freezeButton.isHidden = true }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM