使粒子系统仅受 SceneKit 中某些类别的物理场的影响?
Make particle system only be affected by certain categories of physics fields in SceneKit?
在 SceneKit 中,可以使 SCNPhysicsBody
不受 SCNPhysicsField
的影响,方法是给它们 categoryBitMask
s,当使用按位与进行比较时,结果值为零.
与字段的类别位掩码相比,类别位掩码产生非零值的实体仍然受其影响。
是否可以对 SCNParticleSystem
中的粒子做同样的事情,这样粒子就不会受到 SCNPhysicsField
的影响(编辑:并且仍然有粒子受到其他物理场的影响), 但某些物理体甚至其他粒子系统 受其影响?
澄清一下:
我想要的是:受 SCNPhysicsField
(特别是线性重力场)影响的 SCNParticleSystem
。这可以通过将粒子系统的 affectedByPhysicsFields
属性 设置为 true 来完成。但是,这会使粒子系统受到场景中所有物理场的影响。我有另一个场(也是一个线性重力场),我只想影响一个 SCNPhysicsBody
,我不想受到粒子系统场的影响。
就目前而言,粒子系统和物理体都会受到这两个场的影响。除非我给他们 categoryBitMasks 告诉他们要与哪些字段交互。除非粒子系统没有 categoryBitMasks,并且如果物理场的 categoryBitMask 不是默认值,它将被任何粒子忽略。
所以我可以设置它,以便其中一个字段通过给它们相同的类别来影响正文。但我不能对粒子做同样的事情。有什么办法可以做到这一点? (使用世界重力作为字段之一是行不通的,因为它也没有 categoryBitMask。)
我实际上已经找到了一个解决方法(目前),只使用粒子系统的加速度 属性 而不是物理场。但我很好奇是否真的可以使用物理场来做到这一点。
编辑:根据要求,这里有一些示例代码。此代码生成受两个物理场影响的球体和受一个物理场影响的粒子系统。评论说明了问题。
let PhysicsCategorySphere = 1 << 0
let PhysicsCategoryParticles = 1 << 1
scene.physicsWorld.gravity = SCNVector3(x: 0, y: 0, z: 0)
let sphere = SCNNode(geometry: SCNSphere(radius: 1))
sphere.physicsBody = SCNPhysicsBody.dynamicBody()
sphere.physicsBody?.categoryBitMask = PhysicsCategorySphere
//only physics fields with categoryBitMasks that match the sphere's can affect it
scene.rootNode.addChildNode(sphere)
let field = SCNPhysicsField.linearGravityField()
field.strength = 9.8
field.direction = SCNVector3(x: 0, y: 1, z: 0)
field.categoryBitMask = PhysicsCategorySphere
//only things with categories that match the field's will be affected by it
let fieldNode = SCNNode()
fieldNode.physicsField = field
scene.rootNode.addChildNode(fieldNode)
let particleSystem = SCNParticleSystem(named: "particles", inDirectory: "")
particleSystem.affectedByPhysicsFields = true
//there is no way that I know of to give the particle system a physics category
let particleNode = SCNNode()
particleNode.addParticleSystem(particleSystem)
scene.rootNode.addChildNode(particleNode)
let particleField = SCNPhysicsField.linearGravityField()
particleField.strength = 20
particleField.direction = SCNVector3(x: 0, y: 0, z: 1)
//particleField.categoryBitMask = PhysicsCategoryParticles
//if the field is given a category, it will no longer affect the particles
//the default is to match all categories, thus the particle field will also affect the sphere
let particleFieldNode = SCNNode()
particleFieldNode.physicsField = particleField
scene.rootNode.addChildNode(particleFieldNode)
好吧,我不知道我怎么忽略了这一点,但答案在 SCNPhysicsField
的 categoryBitMask
属性.
的文档中是正确的
To determine whether a field affects the particles spawned by an
SCNParticleSystem object, SceneKit performs the same check using the
categoryBitMask property of the node containing the particle system.
在 SceneKit 中,可以使 SCNPhysicsBody
不受 SCNPhysicsField
的影响,方法是给它们 categoryBitMask
s,当使用按位与进行比较时,结果值为零.
与字段的类别位掩码相比,类别位掩码产生非零值的实体仍然受其影响。
是否可以对 SCNParticleSystem
中的粒子做同样的事情,这样粒子就不会受到 SCNPhysicsField
的影响(编辑:并且仍然有粒子受到其他物理场的影响), 但某些物理体甚至其他粒子系统 受其影响?
澄清一下:
我想要的是:受 SCNPhysicsField
(特别是线性重力场)影响的 SCNParticleSystem
。这可以通过将粒子系统的 affectedByPhysicsFields
属性 设置为 true 来完成。但是,这会使粒子系统受到场景中所有物理场的影响。我有另一个场(也是一个线性重力场),我只想影响一个 SCNPhysicsBody
,我不想受到粒子系统场的影响。
就目前而言,粒子系统和物理体都会受到这两个场的影响。除非我给他们 categoryBitMasks 告诉他们要与哪些字段交互。除非粒子系统没有 categoryBitMasks,并且如果物理场的 categoryBitMask 不是默认值,它将被任何粒子忽略。
所以我可以设置它,以便其中一个字段通过给它们相同的类别来影响正文。但我不能对粒子做同样的事情。有什么办法可以做到这一点? (使用世界重力作为字段之一是行不通的,因为它也没有 categoryBitMask。)
我实际上已经找到了一个解决方法(目前),只使用粒子系统的加速度 属性 而不是物理场。但我很好奇是否真的可以使用物理场来做到这一点。
编辑:根据要求,这里有一些示例代码。此代码生成受两个物理场影响的球体和受一个物理场影响的粒子系统。评论说明了问题。
let PhysicsCategorySphere = 1 << 0
let PhysicsCategoryParticles = 1 << 1
scene.physicsWorld.gravity = SCNVector3(x: 0, y: 0, z: 0)
let sphere = SCNNode(geometry: SCNSphere(radius: 1))
sphere.physicsBody = SCNPhysicsBody.dynamicBody()
sphere.physicsBody?.categoryBitMask = PhysicsCategorySphere
//only physics fields with categoryBitMasks that match the sphere's can affect it
scene.rootNode.addChildNode(sphere)
let field = SCNPhysicsField.linearGravityField()
field.strength = 9.8
field.direction = SCNVector3(x: 0, y: 1, z: 0)
field.categoryBitMask = PhysicsCategorySphere
//only things with categories that match the field's will be affected by it
let fieldNode = SCNNode()
fieldNode.physicsField = field
scene.rootNode.addChildNode(fieldNode)
let particleSystem = SCNParticleSystem(named: "particles", inDirectory: "")
particleSystem.affectedByPhysicsFields = true
//there is no way that I know of to give the particle system a physics category
let particleNode = SCNNode()
particleNode.addParticleSystem(particleSystem)
scene.rootNode.addChildNode(particleNode)
let particleField = SCNPhysicsField.linearGravityField()
particleField.strength = 20
particleField.direction = SCNVector3(x: 0, y: 0, z: 1)
//particleField.categoryBitMask = PhysicsCategoryParticles
//if the field is given a category, it will no longer affect the particles
//the default is to match all categories, thus the particle field will also affect the sphere
let particleFieldNode = SCNNode()
particleFieldNode.physicsField = particleField
scene.rootNode.addChildNode(particleFieldNode)
好吧,我不知道我怎么忽略了这一点,但答案在 SCNPhysicsField
的 categoryBitMask
属性.
To determine whether a field affects the particles spawned by an SCNParticleSystem object, SceneKit performs the same check using the categoryBitMask property of the node containing the particle system.