如何设置 SceneKit 碰撞检测 [英] How to set up SceneKit collision detection

查看:45
本文介绍了如何设置 SceneKit 碰撞检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我已经仔细阅读了文档,但无法弄清楚如何在场景套件中设置碰撞检测.有人可以举个例子吗?请帮助我非常渴望解决这个问题.谢谢!

Hello I have pored over the documentation and can not figure out how to set up collision detection in scene kit. Can some one please show an example. Please help I am very desperate to figure this out. Thank you!

您好 非常感谢您,很抱歉我忘记提及我的项目正在 swift 中.没什么大不了的,我可以自己翻译大部分内容.

Hello Thank you very much, I'm sorry I forgot to mention my project is in swift. No big deal I can translate my self for the most part.

当对象相互碰撞和反弹时,我让位掩码正常工作.但是我似乎无法使该功能正常工作

I have the BitMasks working correctly as the objects collide and bounce with each other. However I can not seem to get the function to work

func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact){
    let contactMask = contact.nodeA.physicsBody!.categoryBitMask | contact.nodeB.physicsBody!.categoryBitMask
    if (contactMask == (CollisionBallCategory | CollisionTerminatorCategory)) {
        println("Collided")
    }
}

查看文档 看来我需要以某种方式将场景物理世界委托分配给此方法.我不知道该怎么做.

Looking at the documentation it appears i need to assign the scenes physics world delegate to this method somehow. I am not sure how to do that.

推荐答案

SceneKit 中碰撞检测的主要内容:

The main things to get about collision detection in SceneKit:

  • 它基于位掩码,它们共同构成了一个表格.
  • 联系代表是您应对冲突的方式.

例如,您可以像这样用简单的英语陈述一些游戏设计:

For example, you might state a bit of game design in plain English like this:

小行星相互撞击(并形成较小的小行星).导弹应该互相穿过,但会摧毁火箭和小行星.火箭不应该对导弹做任何事情(只能相反),但是如果一个导弹太靠近另一个或小行星,你就会遇到严重的问题,你今天不会去太空.

Asteroids hit each other (and make smaller asteroids). Missiles should pass through each other, but destroy rockets and asteroids. Rockets shouldn't do anything to missiles (only the other way around), but if one gets too close to another or to an asteroid you are having a bad problem and you will not go to space today.

通过碰撞检测实现这一点的第一步是根据哪些对交互来编码该设计.你可以用一个表格来做到这一点:

The first step to realizing that with collision detection is to codify that design in terms of which pairs interact. You can do this with a table:

         | Missile | Rocket | Asteroid
--------------------------------------
Missile  | No      | Yes    | Yes
Rocket   | No      | Yes    | Yes
Asteroid | No      | No     | Yes

然后,您可以将表的标题转换为一组类别常量,以便在您的代码中使用.

Then you can turn the headers of the table into a set of category constants for use in your code.

typedef NS_OPTIONS(NSUInteger, CollisionCategory) {
    CollisionCategoryMissile    = 1 << 0,
    CollisionCategoryRocket     = 1 << 1,
    CollisionCategoryAsteroid   = 1 << 2,
};

missile.physicsBody.categoryBitMask = CollisionCategoryMissile;
rocket.physicsBody.categoryBitMask = CollisionCategoryRocket;
asteroid.physicsBody.categoryBitMask = CollisionCategoryAsteroid;

对这些常量使用按位或来创建填充表的 collisionBitMask 值.

Use bitwise OR on these constants to create collisionBitMask values that fill in the table.

missile.physicsBody.collisionBitMask =
    CollisionCategoryRocket | CollisionCategoryAsteroid;
rocket.physicsBody.collisionBitMask =
    CollisionCategoryRocket | CollisionCategoryAsteroid;
asteroid.physicsBody.collisionBitMask = CollisionCategoryAsteroid;

这就是让 SceneKit 为您解决碰撞(即,物体相互反弹)所需的全部内容.

That's all you need to make SceneKit resolve collisions for you (that is, bounce objects off each other).

如果你还想收到碰撞通知(这样你就可以让导弹炸毁东西,让你的船撞上小行星结束游戏),你需要设置一个 联系代表,了解您的场景物理world 并实现一个或多个 联系委托方法,在联系发生时调用.

If you also want to be notified of collisions (so you can make missiles blow stuff up, and running your ship into an asteroid end the game), you'll need to set a contact delegate on your scene's physics world and implement one or more of the contact delegate methods that get called when a contact happens.

在您的联系委托方法中(例如,physicsWorld:didBeginContact:),你需要找出哪些类别的身体参与了接触,哪些是哪个,所以你可以得到你的代码来做你的游戏为碰撞所做的一切:

In your contact delegate method (say, physicsWorld:didBeginContact:), you'll need to find out which categories of bodies were involved in the contact, and which was which, so you can get to your code that does whatever your game does for the collision:

- (void)physicsWorld:(SCNPhysicsWorld *)world didBeginContact:(SCNPhysicsContact *)contact
{
    CollisionCategory contactMask =
        contact.nodeA.physicsBody.categoryBitMask | contact.nodeB.physicsBody.categoryBitMask;

    // first, sort out what kind of collision
    if (contactMask == (CollisionCategoryMissile | CollisionCategoryRocket)) {
        // next, sort out which body is the missile and which is the rocket
        // and do something about it
        if (contact.nodeA.physicsBody.categoryBitMask == CollisionCategoryMissile) {
            [self hitRocket:contact.nodeB withMissile:contact.nodeA];
        } else {
            [self hitRocket:contact.nodeA withMissile:contact.nodeB];
        }
    } else if (contactMask == (CollisionCategoryMissile | CollisionCategoryAsteroid)) {
        // ... and so on ...
    }
}

把这段代码放在你的一个类中(一个视图控制器,也许——只要你保持游戏逻辑是好的),并使该类声明符合 SCNPhysicsContactDelegate 协议.

Put this code in one of your classes (a view controller, maybe — wherever you keep your game logic is good), and make that class declare conformance to the SCNPhysicsContactDelegate protocol.

@interface ViewController: UIViewController <SCNPhysicsContactDelegate>

然后将该对象作为联系代理指定给场景的物理世界:

Then assign that object to your scene's physics world as the contact delegate:

// in initial setup, where presumably you already have a reference to your scene
scene.physicsWorld.contactDelegate = self

了解更多

SCNPhysicsBody 参考文档.Apple 有一些使用碰撞检测的示例代码——它是 WWDC 中演示大杂烩的一部分 幻灯片demo 示例应用程序,以及 车辆物理 演示也是.

Learning more

There's a little bit about collision resolution in the SCNPhysicsBody reference documentation. And Apple has some sample code that uses collision detection — it's part of the smorgasbord of demos in the WWDC slides and demo sample apps, and in the vehicle physics demo, too.

除此之外,SceneKit 的碰撞处理模型几乎与 SpriteKit 的完全相同,因此 SpriteKit 编程指南对于理解 SceneKit 中的相同内容也很有用.

Beyond that, SceneKit's collision handling model is almost exactly the same as SpriteKit's, so almost everything in the SpriteKit programming guide is also useful for understanding the same stuff in SceneKit.

这篇关于如何设置 SceneKit 碰撞检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆